SQL:从多行获取单个结果ID

时间:2019-01-24 15:23:37

标签: mysql

我有两个看起来像这样的表:

conversations

conversation_id | type    | updated_at
     50         | private | 2018-01-01 15:50:51
     30         | group   | 2019-01-01 15:50:49
    100         | private | 2018-01-01 15:50:55

conversation_participants

user_id | conversation_id
1       | 100
3       | 50
5       | 99
6       | 50
6       | 30
3       | 30
2       | 30

现在如何根据两个conversation_id和对话类型来选择user_id

例如,给我来自私人用户3和6的conversation_id。这样我就可以得到conversation_id 50。

到目前为止我的方法:

SELECT * 
FROM conversation_participants as cp 
    LEFT JOIN conversations as c 
       ON c.conversation_id = cp.conversation_id
 WHERE c.type = 'private' 

但是如何根据不同的行来获取conversation_id

2 个答案:

答案 0 :(得分:1)

首先,您需要知道哪些会话是私人的

SELECT conversation_id 
FROM conversations c
WHERE c.type = 'private' 

然后您需要使用SELF JOIN查看用户3和6进行的对话

SELECT conversation_id
FROM conversation_participants cp1
JOIN conversation_participants cp2
  ON cp1.conversation_id = cp2.conversation_id
WHERE cp1 = 3
  AND cp2 = 6 

现在您只过滤私人对话

SELECT conversation_id
FROM conversation_participants cp1
JOIN conversation_participants cp2
  ON cp1.conversation_id = cp2.conversation_id
WHERE conversation_id IN (  SELECT conversation_id 
                            FROM conversations c
                            WHERE c.type = 'private' )
 AND cp1 = 3
 AND cp2 = 6

您还可以使用第三个联接

SELECT conversation_id
FROM conversation_participants cp1
JOIN conversation_participants cp2
  ON cp1.conversation_id = cp2.conversation_id
JOIN conversations c
  ON cp1.conversation_id = c.conversation_id   
WHERE c.type = 'private' 
 AND cp1 = 3
 AND cp2 = 6

答案 1 :(得分:0)

我建议您首先根据参与者选择对话。例如:

SELECT * 
FROM conversation_participants cp
WHERE cp.user_id IN (3, 6)

要仅包含私人对话,您必须将conversation_participants加入conversations

SELECT * 
FROM conversation_participants cp
    INNER JOIN conversations c ON
        c.conversation_id = cp.conversation_id
WHERE
    cp.user_id IN (3, 6)
    AND c.type = 'private'

当然,此查询将为对话中的每个用户包含一行。如果您只希望有1行,则可以按会话分组。像这样:

SELECT
    c.conversation_id,
    c.updated_at,
    COUNT(*) AS participant_count
FROM conversation_participants cp
    INNER JOIN conversations c ON
        c.conversation_id = cp.conversation_id
WHERE
    cp.user_id IN (3, 6)
    AND c.type = 'private'
 GROUP BY 
    c.conversation_id,
    c.updated_at

您将需要使用GROUPING子句,并添加一个HAVING子句以优化查询(尤其是如果您要搜索指定两个以上参与者的对话时):< / p>

SELECT
    c.conversation_id,
    COUNT(*) AS participant_count
FROM conversations c
    INNER JOIN conversation_participants cp ON
        cp.conversation_id = c.conversation_id
WHERE
    c.type = 'private'
    AND cp.user_id IN (3, 6)
 GROUP BY c.conversation_id
 HAVING COUNT(*) = 2