我有一张表,其中有些条目未正确填写。目前,我无法修复表格的填充方式,因此对于我的Select语句,我需要解决这个问题。这是它的样子:
Name | Address | Value | Date
--------------------------------
Peter | New York | 10 | 03-26-18
Peter | | 20 | 03-27-18
Peter | Chicago | 15 | 03-28-18
在样本中,我需要用下一个日期的地址值填充缺失的地址,例如芝加哥。最终输出应如下所示:
Name | Address | Value | Date
--------------------------------
Peter | New York | 10 | 03-26-18
Peter | Chicago | 20 | 03-27-18
Peter | Chicago | 15 | 03-28-18
有一个边缘情况,在同一日期可能有两个同名的条目。在这种情况下,任何一个条目都可以选择作为地址。如果这不起作用,那也没关系,一个不包括边缘案例的解决方案已经帮助我,因为我的所有尝试都导致了重复的条目。
谢谢!
答案 0 :(得分:0)
试试这个:
UPDATE A
SET A.Address=B.Address
FROM TABLE_NAME A
JOIN TABLE_NAME B
ON A.NAME=B.NAME AND A.DATE=DATEADD(DD, -1, B.DATE)
WHERE A.Address IS NULL;
查看有效的DEMO on SQL Fiddle。
答案 1 :(得分:0)
假设您选择的表格中存在某种ID
,您可以使用LEFT JOIN
表格自行执行此操作,并根据{{1}选择下一条记录的条件当Date
列为null或为空时,仅使用联接结果。这应该处理您的边缘情况和非连续日期。 (将Address
替换为您的表名)
test
答案 2 :(得分:0)
好的,我重写了原始查询。我没有考虑到多个缺失值,因为您的原始表没有多个缺失,但我首先应该考虑到这一点。这应该是你正在寻找的。希望它有所帮助。
表:
CREATE TABLE [dbo].[Persons](
ID int IDENTITY(1,1) PRIMARY KEY,
[Name] [varchar](255) NULL,
[Address] [varchar](255) NULL,
[Date] [datetime] NULL
) ON [PRIMARY]
INSERT INTO Persons (Name, Address, Date)
VALUES
('Peter', 'New York', '2018-03-26'),
('Peter', NULL, '2018-03-27'),
('Peter', 'Chicago', '2018-03-28'),
('Peter', NULL, '2018-03-29'),
('Peter', NULL, '2018-03-31'),
('Peter', NULL, '2018-04-01'),
('Peter', NULL, '2018-04-02'),
('Peter', NULL, '2018-04-03'),
('Peter', 'Michigan', '2018-04-04')
GO
<强>查询:强>
WITH CTE1(Name, Address, Date, DateRank) AS (
SELECT Name, Address, Date, RANK() OVER (PARTITION BY Name ORDER BY Date ASC) AS DateRank FROM Persons
),
CTE2(Name, Address, Date, DateRank) AS (
SELECT Name, Address, Date, DateRank FROM CTE1 WHERE Address IS NOT NULL
)
SELECT
x.Name,
x.Address,
CASE WHEN z.DateRank IS NULL
THEN COALESCE((SELECT TOP(1) ADDRESS FROM CTE2 WHERE x.DateRank < CTE2.daterank), 'NA')
ELSE z.Address
END AS CombinedAddress,
x.Date
FROM CTE1 x
LEFT JOIN CTE2 z ON x.DateRank = z.DateRank
ORDER BY x.Date ASC
<强>结果:强>
Name | Address | CombinedAddress | Date
----------------------------------------
Peter New York New York 2018-03-26
Peter NULL Chicago 2018-03-27
Peter Chicago Chicago 2018-03-28
Peter NULL Michigan 2018-03-29
Peter NULL Michigan 2018-03-31
Peter NULL Michigan 2018-04-01
Peter NULL Michigan 2018-04-02
Peter NULL Michigan 2018-04-03
Peter Michigan Michigan 2018-04-04
就我个人而言,我喜欢Rank功能。将CTE与Rank()结合使用可以为以后的格式化提供大量精细控制。这就是我提出的。希望它有所帮助。
表:
CREATE TABLE [dbo].[Persons](
[Id] [int] NULL,
[Name] [varchar](255) NULL,
[Address] [varchar](255) NULL,
[Date] [datetime] NULL
) ON [PRIMARY]
INSERT INTO Persons (Id, Name, Address, Date)
VALUES
(1, 'Peter', 'New York', '2018-03-26'),
(2, 'Peter', 'NULL', '2018-03-27'),
(3, 'Peter', 'Chicago', '2018-03-28'),
(4, 'Peter', 'NULL', '2018-03-29'),
(5, 'Peter', 'Michigan', '2018-03-31')
GO
查询:
WITH CTE1(Name, Address, Date, DateRank) AS (
SELECT Name, Address, Date, RANK() OVER (PARTITION BY Name ORDER BY Date DESC) AS DateRank FROM Persons
),
CTE2(Name, Address, Date, DateRank) AS (
SELECT Name, Address, Date, RANK() OVER (PARTITION BY Name ORDER BY Date DESC) + 1 AS DateRank FROM Persons
),
Query(Name, Address, Date, CombinedAddress) AS (
Select x.Name,
x.Address,
x.Date,
Address = CASE
WHEN x.DateRank % 2 = 0 THEN COALESCE(z.Address, 'NA')
ELSE COALESCE(x.Address, 'NA')
END
FROM CTE1 x
LEFT JOIN CTE2 z ON x.DateRank = z.DateRank
)
SELECT * FROM Query ORDER BY Date ASC