22,209
社区成员
发帖
与我相关
我的任务
分享
select COUNT(*) as Num,SenderID,ReceiverID from tb_Letter where SenderID in(select distinct SenderID as sid from tb_Letter where ReceiverID=2 ) and ( ReceiverID=2 and Receiver_Del_State=0) or ( SenderID=2 and Sender_Del_State=0) group by ReceiverID,SenderID
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt WHERE tt.rn=1
[/quote]
这个分区函数不太明白
我的一次对话的多条记录中ReceiverID和SendreID都有可能是一样的,要是把这俩字段中值都为2的也加到order by后面,那最后的tt.rn这里我不知道怎么根据条件来取,因为我的参数就是SenderID或ReceiverID,但是这里条件是ROW_NUMBER
我不知道怎么去查了。
这是我改的你之前的那个写法
select distinct case when tt.SenderID<tt.ReceiverID then tt.SenderID else tt.ReceiverID end as SenderID,case when tt.SenderID<tt.ReceiverID then tt.ReceiverID else tt.SenderID end as ReceiverID
from (select COUNT(*) as Num,SenderID,ReceiverID from tb_Letter where SenderID in(select distinct SenderID as sid from tb_Letter where SenderID=2 or ReceiverID=2 ) and ( ReceiverID=2 and Receiver_Del_State=0) or ( SenderID=2 and Sender_Del_State=0) group by ReceiverID,SenderID) tt
[/quote]
那个Row_number实现的功能是:
先将SenderID和ReceiverID从新按照同一个规则(小的在前,大的在后)重新生成两个值,其实就是不考虑收和发,单纯读取双方的值,那么2---->5和5---->2的到的是相同的值
然后在这个基础上,为相同的值生成序号(这个序号的范围是具有相同的值,如果值变了,重新排序)
而你需要的相同的值总仅取一条,那么就加上rn=1 (如果仅有一条,rn也是等于1)
比如将你的数据弄多点:
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union ALL
select 1,2,2 union ALL
select 10,2,2 union ALL
select 1,2,1 union all
select 5,2,5 union ALL
select 15,2,5 union ALL
select 10,5,2 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt
/*
1--2和2--1 认为相同,有两条。所以序号是1到2,2和5之间有4条,所以序号是1到4,最终你每种就取一条,所以再加个rn=1就行了(哪一条你想保留,就让它的rn=1,在ROW_Number的Order By里做文章)
num SenderID ReceiverID rn
1 1 2 1
1 2 1 2
10 2 2 1
1 2 2 2
1 2 3 1
15 2 5 1
10 5 2 2
1 5 2 3
5 2 5 4
*/
[/quote]
噢,我明白了,先过滤分区具有相同值的记录,刚好就是两个用户间的会话,再根据这个相同值的基础生成序号,再根据序号来确保唯一性
相同的只取(or仅有一条)都是rn=1,要是需要确保用户间有互动会话的话就是rn=2。
这种貌似判断的条件更多了,真不错。我之前想的思路都反了
厉害厉害,灰常感谢大神
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt WHERE tt.rn=1
[/quote]
这个分区函数不太明白
我的一次对话的多条记录中ReceiverID和SendreID都有可能是一样的,要是把这俩字段中值都为2的也加到order by后面,那最后的tt.rn这里我不知道怎么根据条件来取,因为我的参数就是SenderID或ReceiverID,但是这里条件是ROW_NUMBER
我不知道怎么去查了。
这是我改的你之前的那个写法
select distinct case when tt.SenderID<tt.ReceiverID then tt.SenderID else tt.ReceiverID end as SenderID,case when tt.SenderID<tt.ReceiverID then tt.ReceiverID else tt.SenderID end as ReceiverID
from (select COUNT(*) as Num,SenderID,ReceiverID from tb_Letter where SenderID in(select distinct SenderID as sid from tb_Letter where SenderID=2 or ReceiverID=2 ) and ( ReceiverID=2 and Receiver_Del_State=0) or ( SenderID=2 and Sender_Del_State=0) group by ReceiverID,SenderID) tt
[/quote]
那个Row_number实现的功能是:
先将SenderID和ReceiverID从新按照同一个规则(小的在前,大的在后)重新生成两个值,其实就是不考虑收和发,单纯读取双方的值,那么2---->5和5---->2的到的是相同的值
然后在这个基础上,为相同的值生成序号(这个序号的范围是具有相同的值,如果值变了,重新排序)
而你需要的相同的值总仅取一条,那么就加上rn=1 (如果仅有一条,rn也是等于1)
比如将你的数据弄多点:
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union ALL
select 1,2,2 union ALL
select 10,2,2 union ALL
select 1,2,1 union all
select 5,2,5 union ALL
select 15,2,5 union ALL
select 10,5,2 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt
/*
1--2和2--1 认为相同,有两条。所以序号是1到2,2和5之间有4条,所以序号是1到4,最终你每种就取一条,所以再加个rn=1就行了(哪一条你想保留,就让它的rn=1,在ROW_Number的Order By里做文章)
num SenderID ReceiverID rn
1 1 2 1
1 2 1 2
10 2 2 1
1 2 2 2
1 2 3 1
15 2 5 1
10 5 2 2
1 5 2 3
5 2 5 4
*/
;with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,3 union all
select 1,3,5 union all
select 1,3,5
)
SELECT DISTINCT a.SenderID,a.ReceiverID
FROM t a
WHERE NOT EXISTS(SELECT * FROM t WHERE a.SenderID = t.ReceiverID AND a.ReceiverID = t.SenderID)
;with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,3 union all
select 1,3,5
)
SELECT CASE WHEN SenderID > ReceiverID THEN SenderID ELSE ReceiverID END AS SenderID,
CASE WHEN SenderID < ReceiverID THEN SenderID ELSE ReceiverID END AS ReceiverID
FROM t
GROUP BY CASE WHEN SenderID > ReceiverID THEN SenderID ELSE ReceiverID END,
CASE WHEN SenderID < ReceiverID THEN SenderID ELSE ReceiverID END
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt WHERE tt.rn=1
[/quote]
这个分区函数不太明白
我的一次对话的多条记录中ReceiverID和SendreID都有可能是一样的,要是把这俩字段中值都为2的也加到order by后面,那最后的tt.rn这里我不知道怎么根据条件来取,因为我的参数就是SenderID或ReceiverID,但是这里条件是ROW_NUMBER
我不知道怎么去查了。
这是我改的你之前的那个写法
select distinct case when tt.SenderID<tt.ReceiverID then tt.SenderID else tt.ReceiverID end as SenderID,case when tt.SenderID<tt.ReceiverID then tt.ReceiverID else tt.SenderID end as ReceiverID
from (select COUNT(*) as Num,SenderID,ReceiverID from tb_Letter where SenderID in(select distinct SenderID as sid from tb_Letter where SenderID=2 or ReceiverID=2 ) and ( ReceiverID=2 and Receiver_Del_State=0) or ( SenderID=2 and Sender_Del_State=0) group by ReceiverID,SenderID) tt
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,2
)
SELECT * FROM (
select *, ROW_NUMBER()OVER(PARTITION BY case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID END ORDER BY GETDATE()) AS rn
from t
) tt WHERE tt.rn=1
SELECT COUNT(*) AS Num ,
SenderID ,
ReceiverID
FROM tb_Letter
WHERE SenderID IN ( SELECT DISTINCT
SenderID AS sid
FROM tb_Letter
WHERE ReceiverID = 2 )
AND (( ReceiverID = 2
AND Receiver_Del_State = 0
)
OR ( SenderID = 2
AND Sender_Del_State = 0
))
with t(num,SenderID,ReceiverID) as (
select 1,1,2 union all
select 1,2,3 union all
select 5,2,5 union all
select 1,5,3
)
select distinct case when SenderID<ReceiverID then SenderID else ReceiverID end ,case when SenderID<ReceiverID then ReceiverID else SenderID end
from t