喜欢你的用户(EXISTS)你还没有聊过(不是EXISTS)

问题描述 投票:0回答:2

如果你是"t1".persona_1_id = 2,预期的结果应该返回persona_id = 4

like
---
id persona_1_id persona_2_id liked
1  2            1            FALSE
2  3            1            TRUE
3  4            2            TRUE  -- 4 likes 2
4  2            4            TRUE  -- 2 likes 4
                                   -- (2 and 4 like each other)

chat_persona
---
id chat_id persona_id  -- but same chat has not been created between 2 and 4
1  1       3
2  1       2
3  2       4
4  2       1
5  3       5
6  3       1

-- so persona_id = 4 is the answer

我试图返回彼此相似的用户,他们之间没有聊天。

“喜欢彼此”的作品,但我正在另外过滤“聊天不存在”:

SELECT DISTINCT
    "t1".id, "t1".read_at as read_at, "t1".created_at as created_at,
    "persona".id as persona_id, "persona".profile_id as profile_id, "persona".name as persona_name, "chat_persona".chat_id as chat_id, "chat_persona".id  as chat_persona_id
                    FROM "like" as "t1"
                        JOIN "persona" ON "t1".persona_2_id = "persona".id
                        JOIN "chat_persona" on "t1".persona_2_id = "chat_persona".persona_id
                    WHERE
                        "t1".persona_1_id = 2
                        AND EXISTS (
                            SELECT 1 
                            FROM "like" as "t2"
                            WHERE 
                                "t1".persona_1_id = "t2".persona_2_id 
                                AND "t1".persona_2_id = "t2".persona_1_id
                                AND "t2".liked = true
                        )
                        AND "t1".liked = true
                        AND "chat_persona".id IS NULL -- throws out the correct rows if ANY person chatted with them already... make sense

而不是AND "chat_persona".id IS NULL,也试过:

AND NOT EXISTS (
                            SELECT 1 
                            FROM "chat_persona" as "t2"
                            WHERE 
                                "t1".persona_1_id = "t2".persona_id 
                                AND "t1".persona_2_id = "t2".persona_id
                        ) -- doesn't throw out any rows

最终答案:

SELECT DISTINCT
    "l1".id, "l1".read_at as read_at, "l1".created_at as created_at,
    "persona".id as persona_id, "persona".profile_id as profile_id, "persona".name as persona_name
                    FROM "like" l1
                    JOIN "persona" ON "l1".persona_2_id = "persona".id
                    WHERE
                        "l1".persona_1_id = 2
                        AND "l1".liked = true
                        AND EXISTS (
                            SELECT 1 
                            FROM "like" l2
                            WHERE 
                                "l1".persona_1_id = "l2".persona_2_id 
                                AND "l1".persona_2_id = "l2".persona_1_id
                                AND "l2".liked = true
                        )
                        AND NOT EXISTS (
                            SELECT 1
                            FROM "chat_persona" c
                            WHERE c.persona_id IN ("l1".persona_1_id, "l1".persona_2_id) 
                            GROUP BY c.chat_id
                            HAVING count(*) = 2
                        )
sql postgresql
2个回答
1
投票

我在想not exists,有一个子查询,检查两者是否在同一个chat

select l.persona_1_id, l.persona_2_id
from l
where not exists (select 1
                  from chats c
                  where c.persona_id in (l.persona_1_id, l.persona_2_id)
                  group by c.chat_id
                  having count(*) = 2  -- both are in chat
                 );

1
投票

我的机器上没有postgres,在SQL服务器上测试过,它给出了你没有聊天的行,并给出4作为人员ID。

您可能必须以这种方式修改查询。我修改了几个连接并且更改存在以不存在并更改了内部查询。你可以在SQL server中看到解决方案,概念应该是一样的。

SELECT DISTINCT
    "t1".id, "t1".read_at as read_at, "t1".created_at as created_at,
    "persona".id as persona_id, "persona".profile_id as profile_id, "persona".name as persona_name, "chat_persona".chat_id as chat_id, "chat_persona".id  as chat_persona_id
                    FROM "like" as "t1"
                        JOIN "persona" ON "t1".persona_2_id = "persona".id
                     --   JOIN "chat_persona" on "t1".persona_2_id = -- 
                    --"chat_persona".persona_id   --removed this join as you are looking 
                    --for the records that don't have chat 
                    WHERE
                        "t1".liked = true --changed it here 
                        AND not EXISTS (
                            SELECT 1 
                            FROM "chat_persona" as "t2" --changed it here 
                            WHERE 
                                "t2".Chat_ID = "t1".persona_1_id 
                                AND "t2".Persona_ID = "t1".persona_2_id

                        )

SQL服务器查询:

 select 1 as ID, 2 as   persona_1_id,  1 as persona_2_id, 'FALSE' as Liked into #templike  union all 
select 2 as ID, 3 as   persona_1_id,  1 as persona_2_id, 'TRUE'  as Liked union all 
select 3 as ID, 4 as   persona_1_id,  2 as persona_2_id, 'TRUE'  as Liked union all   
select 4 as ID, 2 as   persona_1_id,  4 as persona_2_id, 'TRUE'  as Liked  


select 1 as ID, 1 as Chat_ID, 3 as Persona_ID into #chat_persona union all
select 2 as ID, 1 as Chat_ID, 2 as Persona_ID union all
select 3 as ID, 2 as Chat_ID, 4 as Persona_ID union all
select 4 as ID, 2 as Chat_ID, 1 as Persona_ID union all
select 5 as ID, 3 as Chat_ID, 5 as Persona_ID union all
select 6 as ID, 3 as Chat_ID, 1 as Persona_ID  

select * from #templike t 
where Liked = 'TRUE' and  not exists (select 1 from #chat_persona cp where cp.Chat_ID = t.persona_1_id and  cp.Persona_ID = t.persona_2_id)

输出:

ID  persona_1_id    persona_2_id    Liked
3   4                     2          TRUE
© www.soinside.com 2019 - 2024. All rights reserved.