我有下表:
AddressId SubBuildingName BuildingName BuildingNumber Postcode
12345 Flat 1 SomeBuilding 80 MK34 1PU
12346 Flat 2 SomeBuilding 80 MK34 1PU
12347 Flat 7 OtherBuilding NULL MK22 9IT
对于每个地址,我需要将 SubBuildingName,BuildingName和BuildingNumber 组合成所有可能的非重复排列中的1个逗号分隔字符串,如下所示:
AddressId AddressLine1
12345 Flat 1, SomeBuilding, 80
12345 Flat 1, 80, SomeBuilding
12345 80, Flat 1, SomeBuilding
12345 80, SomeBuilding, Flat 1
12345 SomeBuilding, Flat 1, 80
12345 SomeBuilding, 80, Flat 1
12346 Flat 1, SomeBuilding, 80
12346 Flat 1, 80, SomeBuilding
12346 80, Flat 1, SomeBuilding
12346 80, SomeBuilding, Flat 1
12346 SomeBuilding, Flat 1, 80
12346 SomeBuilding, 80, Flat 1
12347 Flat 7, OtherBuilding
12347 OtherBuilding, Flat 7
答案 0 :(得分:2)
如果您提前知道要使用哪些列,则可以使用UNPIVOT
和多个自连接来实现所有排列效果,而无需编写二十四个语句,例如以下内容:
DECLARE @Permutations TABLE (ID INT IDENTITY(1,1), v1 VARCHAR(10), v2 VARCHAR(10), v3 VARCHAR(10), v4 VARCHAR(10))
INSERT INTO @Permutations (v1, v2, v3, v4) VALUES ('a', 'b', 'c', 'd')
INSERT INTO @Permutations (v1, v2, v3, v4) VALUES ('w', 'x', 'y', 'z');
WITH alldata AS (
SELECT ID, Value, ValName
FROM
@Permutations
UNPIVOT
(Value FOR ValName IN (v1, v2, v3, v4)) up
)
SELECT
one.ID AS AddressID,
one.Value + ',' + two.Value + ',' + three.Value + ',' + four.Value AS AddressLine1
FROM
alldata one
INNER JOIN
alldata two ON
one.ID = two.ID AND
one.ValName <> two.ValName
INNER JOIN
alldata three ON
one.ID = three.ID AND
one.ValName <> three.ValName AND
two.ValName <> three.ValName
INNER JOIN
alldata four ON
one.ID = four.ID AND
one.ValName <> four.ValName AND
two.ValName <> four.ValName AND
three.ValName <> four.ValName
ORDER BY AddressID, AddressLine1
编辑:阅读自从我开始编写代码以来发表的评论,我不清楚OP是否会满足于看到这样的代码(四个列的四个语句而不是二十四个UNION,五个用于五,等)或需要整个事物是动态的。如果您正在寻找一种编写最小代码而不需要手动计算每种可能排列的技术,那么这个答案就会满足。
答案 1 :(得分:1)
通过它的本质联盟将做一个独特的。 Coalesce用于处理空值 每个语句处理6个不同的潜在订单
SELECT AddressId,
CONCAT(coalesce(SubBuildingName,''), ', ',
coalesce(BuildingName,''), ', ',
coalesce(BuildingNumber,'')
) AS AddressLine1
FROM MyTable
UNION
SELECT AddressId,
CONCAT(coalesce(SubBuildingName,''), ', ',
coalesce(BuildingNumber,''), ', ',
coalesce(BuildingName,'')
) AS AddressLine1
FROM MyTable
UNION
SELECT AddressId,
CONCAT(coalesce(BuildingNumber,''), ', ',
coalesce(BuildingName,''), ', ',
coalesce(SubBuildingName,'')
) AS AddressLine1
FROM MyTable
UNION
SELECT AddressId,
CONCAT(coalesce(BuildingNumber,''), ', ',
coalesce(SubBuildingName,''), ', ',
coalesce(BuildingName,'')
) AS AddressLine1
FROM MyTable
UNION
SELECT AddressId,
CONCAT(coalesce(BuildingName,''), ', ',
coalesce(SubBuildingName,''), ', ',
coalesce(BuildingNumber,'')
) AS AddressLine1
FROM MyTable
UNION
SELECT AddressId,
CONCAT(coalesce(BuildingName,''), ', ',
coalesce(BuildingNumber,''), ', ',
coalesce(SubBuildingName,'')
) AS AddressLine1
FROM MyTable