Sql server TSQL:通过对值进行分组和连接来合并两个集合
我有两个表,每个表中有200多万行。我需要合并它们,性能非常重要 合并后需要连接这些标志 表1 表2 表3-两个表上的合并标志Sql server TSQL:通过对值进行分组和连接来合并两个集合,sql-server,tsql,Sql Server,Tsql,我有两个表,每个表中有200多万行。我需要合并它们,性能非常重要 合并后需要连接这些标志 表1 表2 表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语言编写了这个
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命令可以有效地执行此操作?您没有提到您使用的是哪个版本的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
您没有提到您正在使用哪个版本的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
如果您没有使用STUFF和FOR XML PATH的SQL Server 2017+的另一个选项,我认为这对2008年很好+ 这里有一个
如果您没有使用STUFF和FOR XML PATH的SQL Server 2017+的另一个选项,我认为这对2008年很好+ 这里有一个
不确定您的桌子有多宽,但下面类似的方法可以工作:
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
不确定您的桌子有多宽,但下面类似的方法可以工作:
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
通过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
通过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
表1中33.1.2.3上的两个标志xc是否需要明确处理?我的意思是,如果表2有33.1.2.3->x,表3会有33.1.2.3->xxc还是33.1.2.3->xc?33.1.2.3会保持xc。。。标志不同表1中33.1.2.3中的两个标志xc是否需要进行明确处理?我的意思是,如果表2有33.1.2.3->x,表3会有33.1.2.3->xxc还是33.1.2.3->xc?33.1.2.3会保持xc。。。旗帜很明显,很不幸,这对我不起作用。我们的SQL兼容度为130,版本为13.0…@realPro我曾考虑过XML路径方法,尽管STRING_AGG要优雅得多,我不确定您使用的是哪个版本。BJones提供的答案似乎是我在String_Agg之前应该做的,谢谢,不幸的是这对我不起作用。我们的SQL兼容度为130,版本为13.0…@realPro我曾考虑过XML路径方法,尽管STRING_AGG要优雅得多,我不确定您使用的是哪个版本。BJones提供的答案似乎是我在使用String_之前应该做的,谢谢!这真的很快!请参阅我发布的答案和您的代码。谢谢!这真的很快!请参阅我发布的答案和您的代码。