我有两个表,每个表有2+百万行。我需要将它们合并,性能非常重要。
合并后需要将这些标志串联起来。
表1
ip flags
-----------
23.4.2.8 x
94.4.7.3 t
12.5.7.9 x
33.1.2.3 xc
表2
ip flags
-----------
23.4.2.8 y
94.4.7.3 t
99.6.7.9 t
表3 -两个表上的合并标志
ip flags
-----------
23.4.2.8 yx -- merged flags, the order of flags is not important
94.4.7.3 t -- merged flags, but distinct
12.5.7.9 x
33.1.2.3 xc
99.6.7.9 t
我在C#中工作,想知道是否有可能使用SQL进行此操作。是否有SQL命令可以有效地做到这一点?
答案 0 :(得分:2)
如果您没有使用STUFF
和FOR XML PATH()
的SQL Server 2017+,则可以选择另一种方法-我认为这对于2008年+来说是不错的选择
这里是SQL Fiddle
SELECT
ip
,STUFF((SELECT ',' + t.flags
FROM(
SELECT ip, flags
FROM table1
UNION ALL
SELECT ip, flags
FROM table2
)t
WHERE t.ip = a.ip
FOR XML PATH('')), 1, 1, '') AS Flags
FROM
(
SELECT ip, flags
FROM table1
UNION ALL
SELECT ip, flags
FROM table2
)a
GROUP BY ip
答案 1 :(得分:1)
您没有提到您使用的是哪个版本的SQL Server,尽管如果是2017+版本,此解决方案将对您有效。
您可以使用STRING_AGG
完成目标。尝试对数据进行以下操作(根据上面的示例数据创建表)
CREATE TABLE #table1(
ip VARCHAR(100)
,flags CHAR(10)
)
GO
CREATE TABLE #table2(
ip VARCHAR(100)
,flags CHAR(10)
)
GO
INSERT INTO #table1 VALUES
('23.4.2.8','x')
,('94.4.7.3','t')
,('12.5.7.9','x')
,('33.1.2.3','xc')
GO
INSERT INTO #table2 VALUES
('23.4.2.8','y')
,('94.4.7.3','t')
,('99.6.7.9','t')
GO
SELECT
ip
,STRING_AGG(RTRIM(flags),',')
FROM
(
SELECT
ip
,flags
FROM #table1
UNION ALL
SELECT
ip
,flags
FROM #table2
)a
GROUP BY ip
答案 2 :(得分:1)
不确定表格的宽度,但是下面的方法可能起作用:
SELECT ISNULL(t.IP, t2.IP) AS IP
, CONCAT(ISNULL(t.flags,’’), ISNULL(t2.flags, ‘’)) AS flags
FROM table1 as t
FULL JOIN table2 as t2 ON t.IP = t2.IP
答案 3 :(得分:0)
通过ssn扩展答案以清除重复的字符。 表现真的很好!
SELECT ISNULL(t.IP, t2.IP) AS IP
, [dbo].[FN_CLEANDUPCHAR](CONCAT(ISNULL(t.block_reason_code,''), ISNULL(t2.block_reason_code, ''))) AS block_reason_code
FROM ##table1 as t FULL JOIN ##table2 as t2
ON t.IP = t2.IP
这是函数:
CREATE FUNCTION [dbo].[FN_CLEANDUPCHAR]
(
@S varchar(20)
)
RETURNS varchar(20)
AS
BEGIN
SELECT
@S = CASE WHEN CHARINDEX(SUBSTRING(@s,Number,1),@s) BETWEEN 1 AND Number-1 THEN STUFF(@s,Number,1,'') ELSE @S END
FROM master.dbo.spt_values
WHERE Number BETWEEN 2 AND LEN(@s) AND type='P'
ORDER BY Number DESC
return @S
END
GO