连接其他列值时删除重复项
Remove duplicate while concatenating other columns values
我的数据 table 如下所示(表 1)
Table1
------------------------------------------
ID | IPaddress | Port | Value
----|---------------|-------|-------------
1 | xx.yy.14.15 | 332 | This is good
------------------------------------------
2 | xx.yy.14.15 | 332 | I can work
------------------------------------------
3 | xx.yy.12.12 | 400 | Looks ok
------------------------------------------
4 | xx.yy.12.12 | 400 | can I work
------------------------------------------
5 | xx.yy.12.12 | 400 | Yes, please
-------------------------------------------
6 | xx.yy.14.16 | 401 | How is this
-------------------------------------------
7 | xx.yy.14.16 | 401 | Looks ok
-------------------------------------------
8 | xx.yy.14.16 | 401 | can I work
-------------------------------------------
9 | xx.yy.14.16 | 401 | Yes, please
-------------------------------------------
想要的结果table:
ID | IPaddress | Port | Value
----|---------------|-------|-----------------------------------------------------------
1 | xx.yy.14.15 | 332 | This is good and I can work
--------------------------------------------------------------------------------------
2 | xx.yy.12.12 | 400 | Looks ok and can I work and Yes, please
---------------------------------------------------------------------------------------
3 | xx.yy.14.16 | 401 | How is this and Looks ok and can I work and Yes, please
---------------------------------------------------------------------------------------
这是我尝试过的方法:
DECLARE @VAR1 VARCHAR(50)
DECLARE @VAR2 VARCHAR(50)
SELECT @VAR1 = T1.VALUE,@VAR2=T2.VALUE
FROM TABLE1 AS T1 INNER JOIN TABLE1 AS T2 ON T1.ID =T2.ID
WHERE T1.IPADDRESS =T2.IPADDRESS
SELECT IPADDRSS,PORT,@VAR1 + ' AND ' +@VAR2 FROM
SELECT T1.*,
ROW_NUMBER() OVER (PARTITION BY T1.IPADDRESS,T1.PORT ORDER BY VALUE) AS NM
FROM TABLE1 AS T1
)TBL
WHERE NM = 1
但是,从上面的查询中,如果只有 2 个重复行,我就能获得所需的输出
(注意:这里我认为 IPADDRESS 和 PORT 是重复的,而其他列不是重复的)
但是,如果在 3 或 4 或 5 行中有相同的 IPADDRESS 和 PORT,我怎样才能达到我想要的结果?请注意,具有相同 IPADDRESS 和 PORT 的行数是动态的,有时可能会超过 10。
那么,如何在获得理想结果的同时处理这种动态情况?
希望我解释正确。请帮忙。谢谢
这是创建分隔列表的答案(通常是逗号,但在您的情况下是 ' 和 ' 分隔)
尝试在该列中使用内容
select rownumber() over (order by IPAddress,Port),IPAddress,Port
,stuff((select ' and ' + value
from table t2
where t1.IPaddress=t2.ipaddress and t1.port=t2.port
order by ID
for XML path(''), type
).value('.','nvarchar(max)')
,1,len(' and '),'') as verbage
from table t1
group by IPAddress,Port
工作方式:
外部查询基本上为您提供 IPAddress、Port
上的分组结果
相关子查询提供与 IPAddress、Port 关联的每一行的分隔列表
内容逻辑是删除第一个'和'
刚刚看到你的评论回复:SQL 2017。应该在前面说过,我一直在研究一种让我伤心的老式聚合技术。 SQL 2017 年给了我们期待已久的 string_agg 功能,这让它变得非常容易:
SELECT
row_number() over (order by IPaddress, Port) ID
,IPaddress
,Port
,string_agg(Value, ' and ')
from Table1
group by
IPaddress
,Port
如果顺序很重要,您可能需要稍微戳一下。
@KeithL 的版本也可以工作,需要一些调试……我看到你刚刚解决了。我,我只是不太喜欢 XML,这就是为什么我正在研究替代品。
你可以试试这个:
select t.* from (
select ROW_NUMBER() over (partition by port order by port) rn,id,port,value=stuff (
( select ' ' + value from @t t
where t.port=t1.port
for xml path ('')),1,1,''
) from @t t1
group by id,port
) t
where rn=1
SELECT
t1.IpAddress,t1.port,
value = STUFF((
SELECT ' and ' + t2.value
FROM Table1 t2
WHERE t1.port = t2.port
FOR XML PATH('')
),2, 3, '')
FROM Table1 t1
GROUP BY t1.port,t1.IpAddress
我的数据 table 如下所示(表 1)
Table1
------------------------------------------
ID | IPaddress | Port | Value
----|---------------|-------|-------------
1 | xx.yy.14.15 | 332 | This is good
------------------------------------------
2 | xx.yy.14.15 | 332 | I can work
------------------------------------------
3 | xx.yy.12.12 | 400 | Looks ok
------------------------------------------
4 | xx.yy.12.12 | 400 | can I work
------------------------------------------
5 | xx.yy.12.12 | 400 | Yes, please
-------------------------------------------
6 | xx.yy.14.16 | 401 | How is this
-------------------------------------------
7 | xx.yy.14.16 | 401 | Looks ok
-------------------------------------------
8 | xx.yy.14.16 | 401 | can I work
-------------------------------------------
9 | xx.yy.14.16 | 401 | Yes, please
-------------------------------------------
想要的结果table:
ID | IPaddress | Port | Value
----|---------------|-------|-----------------------------------------------------------
1 | xx.yy.14.15 | 332 | This is good and I can work
--------------------------------------------------------------------------------------
2 | xx.yy.12.12 | 400 | Looks ok and can I work and Yes, please
---------------------------------------------------------------------------------------
3 | xx.yy.14.16 | 401 | How is this and Looks ok and can I work and Yes, please
---------------------------------------------------------------------------------------
这是我尝试过的方法:
DECLARE @VAR1 VARCHAR(50)
DECLARE @VAR2 VARCHAR(50)
SELECT @VAR1 = T1.VALUE,@VAR2=T2.VALUE
FROM TABLE1 AS T1 INNER JOIN TABLE1 AS T2 ON T1.ID =T2.ID
WHERE T1.IPADDRESS =T2.IPADDRESS
SELECT IPADDRSS,PORT,@VAR1 + ' AND ' +@VAR2 FROM
SELECT T1.*,
ROW_NUMBER() OVER (PARTITION BY T1.IPADDRESS,T1.PORT ORDER BY VALUE) AS NM
FROM TABLE1 AS T1
)TBL
WHERE NM = 1
但是,从上面的查询中,如果只有 2 个重复行,我就能获得所需的输出 (注意:这里我认为 IPADDRESS 和 PORT 是重复的,而其他列不是重复的)
但是,如果在 3 或 4 或 5 行中有相同的 IPADDRESS 和 PORT,我怎样才能达到我想要的结果?请注意,具有相同 IPADDRESS 和 PORT 的行数是动态的,有时可能会超过 10。 那么,如何在获得理想结果的同时处理这种动态情况?
希望我解释正确。请帮忙。谢谢
这是创建分隔列表的答案(通常是逗号,但在您的情况下是 ' 和 ' 分隔)
尝试在该列中使用内容
select rownumber() over (order by IPAddress,Port),IPAddress,Port
,stuff((select ' and ' + value
from table t2
where t1.IPaddress=t2.ipaddress and t1.port=t2.port
order by ID
for XML path(''), type
).value('.','nvarchar(max)')
,1,len(' and '),'') as verbage
from table t1
group by IPAddress,Port
工作方式:
外部查询基本上为您提供 IPAddress、Port
上的分组结果相关子查询提供与 IPAddress、Port 关联的每一行的分隔列表
内容逻辑是删除第一个'和'
刚刚看到你的评论回复:SQL 2017。应该在前面说过,我一直在研究一种让我伤心的老式聚合技术。 SQL 2017 年给了我们期待已久的 string_agg 功能,这让它变得非常容易:
SELECT
row_number() over (order by IPaddress, Port) ID
,IPaddress
,Port
,string_agg(Value, ' and ')
from Table1
group by
IPaddress
,Port
如果顺序很重要,您可能需要稍微戳一下。
@KeithL 的版本也可以工作,需要一些调试……我看到你刚刚解决了。我,我只是不太喜欢 XML,这就是为什么我正在研究替代品。
你可以试试这个:
select t.* from (
select ROW_NUMBER() over (partition by port order by port) rn,id,port,value=stuff (
( select ' ' + value from @t t
where t.port=t1.port
for xml path ('')),1,1,''
) from @t t1
group by id,port
) t
where rn=1
SELECT
t1.IpAddress,t1.port,
value = STUFF((
SELECT ' and ' + t2.value
FROM Table1 t2
WHERE t1.port = t2.port
FOR XML PATH('')
),2, 3, '')
FROM Table1 t1
GROUP BY t1.port,t1.IpAddress