将多行合并为一行,在 SQL 服务器中的两列之间交换相同的值
Merge Multiple Rows to One Row having Same value swapped between 2 columns In SQL Server
我正在开发一个基于 API 的简单聊天模块。我正在尝试获取特定用户的聊天对话,但由于 2 列彼此之间交换了相同的值,导致我的数据重复。
我想合并具有在 2 列之间交换的相同值的行,并且合并的行应基于数据库中插入的最新条目。
数据如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
2 3 1 hi 12:00PM
3 1 3 how are you? 12:15PM
4 3 1 I am fine. 12:30PM
5 4 5 Hi! 04:30PM
6 5 4 Hello 04:35PM
7 1 5 Hola! 06:30PM
例如,如果用户 ID 为 1,我的结果需要如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
4 3 1 I am fine. 12:30PM
7 1 5 Hola! 06:30PM
如果 Id 是 5 那么结果将是这样的:
Id To From Message ConversationTime
6 5 4 Hello 04:35PM
7 1 5 Hola! 06:30PM
我的结果集如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
3 1 3 how are you? 12:15PM
4 3 1 I am fine. 12:30PM
7 1 5 Hola! 06:30PM
任何帮助将不胜感激。提前致谢!
想法与链接副本Get top 1 row of each group 相同;只需使用 CASE
表达式即可获取 other 用户的 ID:
DECLARE @ID int = 1;
WITH RNs AS(
SELECT ID,
[To], --TO is a reserved keyword and should not be used for object names
[From], --FROM is a reserved keyword and should not be used for object names
Message,
ConversationTime, --I assume this is a time
ROW_NUMBER() OVER (PARTITION BY CASE [To] WHEN @ID THEN [From] ELSE [To] END ORDER BY ConversationTime DESC) AS RN --TO and FROM are reserved keywords and should not be used for object names
FROM dbo.YourTable
WHERE @ID IN ([To],[From])) --TO and FROM are reserved keywords and should not be used for object names
SELECT ID,
[To], --TO is a reserved keyword and should not be used for object names
[From], --FROM is a reserved keyword and should not be used for object names
Message,
ConversationTime --I assume this is a time
FROM RN
WHERE RN = 1;
SQL 服务器允许您在没有 case
表达式的情况下通过反透视数据然后使用 window 函数来执行此操作:
select t.*
from (select t.*,
row_number() over (partition by v.user_other order by t.conversationTime desc) as seqnum
from t cross apply
(values (t.to, t.from), (t.from, to.to)
) v(user, user_other)
where v.user = 1
) t
where seqnum = 1;
我正在开发一个基于 API 的简单聊天模块。我正在尝试获取特定用户的聊天对话,但由于 2 列彼此之间交换了相同的值,导致我的数据重复。
我想合并具有在 2 列之间交换的相同值的行,并且合并的行应基于数据库中插入的最新条目。
数据如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
2 3 1 hi 12:00PM
3 1 3 how are you? 12:15PM
4 3 1 I am fine. 12:30PM
5 4 5 Hi! 04:30PM
6 5 4 Hello 04:35PM
7 1 5 Hola! 06:30PM
例如,如果用户 ID 为 1,我的结果需要如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
4 3 1 I am fine. 12:30PM
7 1 5 Hola! 06:30PM
如果 Id 是 5 那么结果将是这样的:
Id To From Message ConversationTime
6 5 4 Hello 04:35PM
7 1 5 Hola! 06:30PM
我的结果集如下所示:
Id To From Message ConversationTime
1 1 2 hello 11:00AM
3 1 3 how are you? 12:15PM
4 3 1 I am fine. 12:30PM
7 1 5 Hola! 06:30PM
任何帮助将不胜感激。提前致谢!
想法与链接副本Get top 1 row of each group 相同;只需使用 CASE
表达式即可获取 other 用户的 ID:
DECLARE @ID int = 1;
WITH RNs AS(
SELECT ID,
[To], --TO is a reserved keyword and should not be used for object names
[From], --FROM is a reserved keyword and should not be used for object names
Message,
ConversationTime, --I assume this is a time
ROW_NUMBER() OVER (PARTITION BY CASE [To] WHEN @ID THEN [From] ELSE [To] END ORDER BY ConversationTime DESC) AS RN --TO and FROM are reserved keywords and should not be used for object names
FROM dbo.YourTable
WHERE @ID IN ([To],[From])) --TO and FROM are reserved keywords and should not be used for object names
SELECT ID,
[To], --TO is a reserved keyword and should not be used for object names
[From], --FROM is a reserved keyword and should not be used for object names
Message,
ConversationTime --I assume this is a time
FROM RN
WHERE RN = 1;
SQL 服务器允许您在没有 case
表达式的情况下通过反透视数据然后使用 window 函数来执行此操作:
select t.*
from (select t.*,
row_number() over (partition by v.user_other order by t.conversationTime desc) as seqnum
from t cross apply
(values (t.to, t.from), (t.from, to.to)
) v(user, user_other)
where v.user = 1
) t
where seqnum = 1;