连接和删除多行
concatenate and de-dupe multiple rows
我有一些采用以下格式的传入行。
| Col1 | Col2 | Col3 |
| 1 | A | 1 |
| 1 | A | 1,2 |
| 1 | A | 1,3 |
| 1 | A | 2,4 |
期望的输出sql是
| Col1 | Col2 | Col3 |
| 1 | A | 1,2,3,4 |
基本上,根据 Col1 和 Col2 对所有行进行分组,然后连接并删除 Col3 中的重复项。
SELECT COL1, COL2, {?????}
FROM TABLEA
GROUP BY COL1, COL2;
此刻我想不通。任何指针将不胜感激。我倾向于 WX2 数据库,但任何符合 ANSI 标准的代码片段都会有所帮助。
对于 SQL 服务器:首先在此 CTE 表上使用 STUFF 方法和 INSERT INTO CTE table.Based 连接所有 col3 值,根据 CTE table.Finally 将所有行作为单个列拆分在 STUFF 的帮助下连接所有 DISTINCT 字符串。
CREATE TABLE #table ( Col1 INT , Col2 VARCHAR(10) , Col3 VARCHAR(10))
INSERT INTO #table ( Col1 , Col2 , Col3 )
SELECT 1 , 'A' , '1' UNION ALL
SELECT 1 , 'A' , '1,2' UNION ALL
SELECT 1 , 'A' , '1,3' UNION ALL
SELECT 1 , 'A' , '2,4'
;WITH CTEValues ( Colval ) AS
(
SELECT STUFF ( ( SELECT ',' + Col3 FROM #table T2 WHERE T2.Col2 =
T1.col2 FOR XML PATH('') ),1,1,'')
FROM #table T1
GROUP BY Col2
)
SELECT * INTO #CTEValues
FROM CTEValues
;WITH CTEDistinct ( SplitValues , SplitRemain ) AS
(
SELECT SUBSTRING(Colval,0,CHARINDEX(',',Colval)),
SUBSTRING(Colval,CHARINDEX(',',Colval)+1,LEN(Colval))
FROM #CTEValues
UNION ALL
SELECT CASE WHEN CHARINDEX(',',SplitRemain) = 0 THEN SplitRemain ELSE
SUBSTRING(SplitRemain,0,CHARINDEX(',',SplitRemain)) END,
CASE WHEN CHARINDEX(',',SplitRemain) = 0 THEN '' ELSE
SUBSTRING(SplitRemain,CHARINDEX(',',SplitRemain)+1,LEN(SplitRemain))
END
FROM CTEDistinct
WHERE SplitRemain <> ''
)
SELECT STUFF ( ( SELECT DISTINCT ',' + SplitValues FROM CTEDistinct T2
FOR XML PATH('') ),1,1,'')
您可以尝试转置或连接函数。困难在于 col3 是 varchar 并且需要进行转换才能获得不同的值。
随着 MySQL :
SELECT col1, col2, GROUP_CONCAT(DISTINCT col3) AS col3 FROM
(SELECT col1, col2, CONVERT(SUBSTR(col3, 1), UNSIGNED INTEGER) AS col3 FROM (
SELECT 1 AS col1, 'A' AS col2, '1' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,2' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,3' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '2,4' AS col3
) AS t
UNION ALL
SELECT col1, col2, CONVERT(SUBSTR(col3, 3), UNSIGNED INTEGER) AS col3 FROM (
SELECT 1 AS col1, 'A' AS col2, '1' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,2' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,3' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '2,4' AS col3
) AS t1
) AS t2
WHERE col3 <> 0
结果:
col1 | col2 | col3
1 | A | 1,2,3,4
对于 Postgres 使用这个:
select col1, col2, string_agg(distinct col3, ',') as col3
from (
select col1, col2, x.col3
from tablea, unnest(string_to_array(col3, ',')) as x(col3)
) t
group by col1, col2;
除 string_to_array()
和 string_agg()
函数外,这在很大程度上符合 ANSI 标准。
我有一些采用以下格式的传入行。
| Col1 | Col2 | Col3 |
| 1 | A | 1 |
| 1 | A | 1,2 |
| 1 | A | 1,3 |
| 1 | A | 2,4 |
期望的输出sql是
| Col1 | Col2 | Col3 |
| 1 | A | 1,2,3,4 |
基本上,根据 Col1 和 Col2 对所有行进行分组,然后连接并删除 Col3 中的重复项。
SELECT COL1, COL2, {?????}
FROM TABLEA
GROUP BY COL1, COL2;
此刻我想不通。任何指针将不胜感激。我倾向于 WX2 数据库,但任何符合 ANSI 标准的代码片段都会有所帮助。
对于 SQL 服务器:首先在此 CTE 表上使用 STUFF 方法和 INSERT INTO CTE table.Based 连接所有 col3 值,根据 CTE table.Finally 将所有行作为单个列拆分在 STUFF 的帮助下连接所有 DISTINCT 字符串。
CREATE TABLE #table ( Col1 INT , Col2 VARCHAR(10) , Col3 VARCHAR(10))
INSERT INTO #table ( Col1 , Col2 , Col3 )
SELECT 1 , 'A' , '1' UNION ALL
SELECT 1 , 'A' , '1,2' UNION ALL
SELECT 1 , 'A' , '1,3' UNION ALL
SELECT 1 , 'A' , '2,4'
;WITH CTEValues ( Colval ) AS
(
SELECT STUFF ( ( SELECT ',' + Col3 FROM #table T2 WHERE T2.Col2 =
T1.col2 FOR XML PATH('') ),1,1,'')
FROM #table T1
GROUP BY Col2
)
SELECT * INTO #CTEValues
FROM CTEValues
;WITH CTEDistinct ( SplitValues , SplitRemain ) AS
(
SELECT SUBSTRING(Colval,0,CHARINDEX(',',Colval)),
SUBSTRING(Colval,CHARINDEX(',',Colval)+1,LEN(Colval))
FROM #CTEValues
UNION ALL
SELECT CASE WHEN CHARINDEX(',',SplitRemain) = 0 THEN SplitRemain ELSE
SUBSTRING(SplitRemain,0,CHARINDEX(',',SplitRemain)) END,
CASE WHEN CHARINDEX(',',SplitRemain) = 0 THEN '' ELSE
SUBSTRING(SplitRemain,CHARINDEX(',',SplitRemain)+1,LEN(SplitRemain))
END
FROM CTEDistinct
WHERE SplitRemain <> ''
)
SELECT STUFF ( ( SELECT DISTINCT ',' + SplitValues FROM CTEDistinct T2
FOR XML PATH('') ),1,1,'')
您可以尝试转置或连接函数。困难在于 col3 是 varchar 并且需要进行转换才能获得不同的值。 随着 MySQL :
SELECT col1, col2, GROUP_CONCAT(DISTINCT col3) AS col3 FROM
(SELECT col1, col2, CONVERT(SUBSTR(col3, 1), UNSIGNED INTEGER) AS col3 FROM (
SELECT 1 AS col1, 'A' AS col2, '1' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,2' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,3' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '2,4' AS col3
) AS t
UNION ALL
SELECT col1, col2, CONVERT(SUBSTR(col3, 3), UNSIGNED INTEGER) AS col3 FROM (
SELECT 1 AS col1, 'A' AS col2, '1' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,2' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '1,3' AS col3 UNION ALL
SELECT 1 AS col1, 'A' AS col2, '2,4' AS col3
) AS t1
) AS t2
WHERE col3 <> 0
结果:
col1 | col2 | col3
1 | A | 1,2,3,4
对于 Postgres 使用这个:
select col1, col2, string_agg(distinct col3, ',') as col3
from (
select col1, col2, x.col3
from tablea, unnest(string_to_array(col3, ',')) as x(col3)
) t
group by col1, col2;
除 string_to_array()
和 string_agg()
函数外,这在很大程度上符合 ANSI 标准。