我要做的是根据ID将多行数据合并为一行。
我遇到的问题是我需要根据条件组合旧数据和新数据。 条件是,如果没有行值,则地址保持不变,如果有值,则根据属性的任何内容更改数据。
我已尝试使用STUFF AND FOR XML PATH进行字符串连接并使用case语句,但我无法获得所需的结果。顺便说一句,我相当绿,所以我可能没有正确使用它。
我已提供以下链接,说明我是如何解决此问题的。 这是漫长的一天,我可能会过度思考它。我想与您的专业人士联系,了解您的想法和可能更好的选择?
http://sqlfiddle.com/#!6/df574d/4/0
数据样本
CREATE TABLE [dbo].[AddressUpdate]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[AddressUpdateID] [int] NOT NULL,
[Property] [varchar](50) NULL,
[OldValue] [varchar](max) NULL,
[NewValue] [varchar](max) NULL,
)
CREATE TABLE [dbo].[Address]
(
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[AddressUpdateID] [int] NOT NULL,
[Address] [nvarchar](256) NULL,
[City] [nvarchar](256) NULL,
[State] [nvarchar](256) NULL,
[Zip] [nvarchar](256) NULL,
[CountryCode] [nchar](3) NULL,
)
INSERT INTO Address
(
--Address.ID,
AddressUpdateID,
Address,
[City],
State,
Zip,
CountryCode
)
VALUES
( 1, '654 5th Ave', 'Los Angelas', 'LA', '65445', 'USA'),
( 2, '123 Broadway Ave', 'Orlando', 'FL', '56476', 'USA'),
( 3, '789 Sunset Lane', 'Oakley', 'Alberta', 'L6H 0P7', 'CAN'),
( 4, '987 Country Dr', 'Flint', 'MI', '89874', 'USA'),
( 5, '741 Fast Street', 'MONTREAL', 'Quebec', 'T8V 0N5', 'CAN')
INSERT INTO AddressUpdate
(
--ID
AddressUpdateID,
Property,
OldValue,
NewValue
)
VALUES
(1, 'Address', '654 5th Ave', '5321 Hollywood'),
(2, 'Address', '123 Broadway Ave', '654 West Village'),
(2, 'City', 'Orlando', 'New York City'),
(2, 'State', 'FL', 'New York'),
(2, 'Zip', '56476', '8642'),
(4, 'Address', '987 Country Dr', '987 Maple Rd'),
(4, 'City', 'Flint', 'Alberta'),
(4, 'State', 'MI', 'GRANDE PRAIRIE'),
(4, 'Zip', '89874', 'T8V 0N5'),
(4, 'CountryCode', 'USA', 'CAN')
我是如何解决它的。
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
BEGIN
DROP TABLE #temp
END
CREATE TABLE #temp
(
AddressUpdateID BIGINT,
Address NVARCHAR(256),
City NVARCHAR(256),
State NVARCHAR(256),
Zip NVARCHAR(256),
CountryCode NCHAR(3)
)
INSERT INTO #temp (AddressUpdateID)
SELECT
DISTINCT a.AddressUpdateID
FROM
Address a
--update address
UPDATE #temp
SET #temp.Address = au.NewValue
FROM AddressUpdate au
WHERE au.addressupdateid = #temp.AddressUpdateID
AND au.property = 'Address'
--SELECT * FROM #temp
--update null address with current value
UPDATE #temp
SET #temp.Address = a.Address
FROM Address a
WHERE #temp.Address IS NULL AND #temp.AddressUpdateID = a.AddressUpdateID
--update city
UPDATE #temp
SET #temp.City = au.NewValue
FROM AddressUpdate au
WHERE au.addressupdateid = #temp.AddressUpdateID
AND au.property = 'City'
--update null city with current value
UPDATE #temp
SET #temp.City = a.City
FROM Address a
WHERE #temp.City IS NULL AND #temp.AddressUpdateID = a.AddressUpdateID
--update state
UPDATE #temp
SET #temp.State = au.NewValue
FROM AddressUpdate au
WHERE au.addressupdateid = #temp.AddressUpdateID
AND au.property = 'State'
--update null State with current value
UPDATE #temp
SET #temp.State = a.State
FROM Address a
WHERE #temp.State IS NULL AND #temp.AddressUpdateID = a.AddressUpdateID
--update zip
UPDATE #temp
SET #temp.Zip = au.NewValue
FROM AddressUpdate au
WHERE au.addressupdateid = #temp.AddressUpdateID
AND au.property = 'Zip'
--update null zip with current value
UPDATE #temp
SET #temp.Zip = a.Zip
FROM Address a
WHERE #temp.Zip IS NULL AND #temp.AddressUpdateID = a.AddressUpdateID
--update country code
UPDATE #temp
SET #temp.CountryCode = au.NewValue
FROM AddressUpdate au
WHERE au.addressupdateid = #temp.AddressUpdateID
AND au.property = 'CountryCode'
--update null country code with current value
UPDATE #temp
SET #temp.CountryCode = a.CountryCode
FROM Address a
WHERE #temp.CountryCode IS NULL AND #temp.AddressUpdateID = a.AddressUpdateID
SELECT
[Old Address] = a.Address + ' ' + a.City +', ' + a.State + ' ' + a.Zip + ' ' + a.CountryCode
,[New Address] = t.Address + ' ' + t.City +', ' + t.State + ' ' + t.Zip + ' ' + t.CountryCode
FROM
Address a
LEFT JOIN #temp t ON t.AddressUpdateID = a.AddressUpdateId
答案 0 :(得分:0)
UNPIVOT
首先Address
表,JOIN
表示AddressUpdate
。之后,使用FOR XML PATH('')
进行字符串连接:
;WITH CteAddressUnpivot(Id, AddressUpdateId, Property, Val) AS(
SELECT
a.Id,
a.AddressUpdateID,
x.Property,
x.Val
FROM Address a
CROSS APPLY( VALUES
('Address', Address),
('City', City),
('State', State),
('Zip', Zip),
('CountryCode', CountryCode)
)x(Property, Val)
)
SELECT
OldAddress = a.Address + ' ' + a.City +', ' + a.State + ' ' + a.Zip + ' ' + a.CountryCode,
NewAddress = x.NewAddress
FROM Address a
CROSS APPLY(
SELECT STUFF((
SELECT ' ' + ISNULL(au.NewValue, cau.Val)
FROM CteAddressUnpivot cau
LEFT JOIN AddressUpdate au
ON au.Property = cau.Property
AND au.AddressUpdateID = cau.AddressUpdateId
WHERE
cau.Id = a.ID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
)x(NewAddress)