我不知道如何問這個問題。我有以下架構:
| message_id | 訊息內容 |
|---|---|
| 1 | 你好世界 |
| 2 | EHLO |
| message_id | 關注用戶 |
|---|---|
| 1 | 勞拉 |
| 1 | 維克 |
| 1 | 約翰 |
| 2 | 勞拉 |
| 2 | 維克 |
如何選擇message_id關注laura 和 vick(并且只有laura 和 vick)。預期結果是 ?[2]`。
我確定這是基本的 SQL,但我沒有找到它。
正如一些答案所質疑的那樣:我使用 PostgreSQL。
謝謝 !
uj5u.com熱心網友回復:
建立一個相關用戶的字串,看看它是否與您正在尋找的內容相匹配。在 PostgreSQL 中,字串連接組函式是STRING_AGG:
select message_id
from mytable
group by message_id
having string_agg(concerned_user, ',' order by concerned_user) = 'laura,vick';
如果表中可能有重復項(同一 message_id 和相關用戶的兩行或多行),則必須添加DISTINCT: string_agg(distinct concerned_user ...)。
uj5u.com熱心網友回復:
如果只有 2 個特定用戶有相同的訊息,那么該訊息將只有 2 個唯一用戶。
每個用戶的計數不會為零。
SELECT message_id
FROM your_table
GROUP BY message_id
HAVING COUNT(DISTINCT concerned_user) = 2
AND COUNT(CASE WHEN concerned_user = 'laura' THEN 1 END) > 0
AND COUNT(CASE WHEN concerned_user = 'vick' THEN 1 END) > 0;
db<>在這里擺弄
uj5u.com熱心網友回復:
在非常基本的 SQL 中,它可以通過使用 WHERE EXISTS / NOT EXISTS 的陳述句來完成,例如(在偽代碼中,真正的 SQL 陳述句如下):
select messages-from-laura
where exists(message-from-vick-with-same-id)
and not exist(message-from-someone-else with same-id)
same-id 指的是 laura-message id。
這是標準 SQL,它適用于 postgresql、mssql(兩者都經過測驗),也可能適用于其他 SQL。
select *
from messages laura_messages
where concerned_user = 'laura'
and (exists (select 1 from messages vick_messages
where vick_messages.message_id = laura_messages.message_id))
and not exists (select 1 from messages other_messages
where other_messages.message_id = laura_messages.message_id
and other_messages.concerned_user not in ('laura','vick'))
注意主表和子查詢表的別名使用(在 SQL 中,您可以在 FROM TableName 子句中的表名之后添加別名)以及 EXISTS 子查詢中第一個訊息 id 的參考。
另請注意,您不需要在子查詢中回傳某些內容,只需存在一些資料,因此執行 SELECT 1 就可以了。
您可以使用連接撰寫等效查詢,但優化器非常擅長重寫查詢,所以它可能是相同的,這個更簡單恕我直言。或者您也可以使用 GROUP 或更復雜的東西,sql 的好處是您通常有多種可能性來撰寫相同的查詢:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/406852.html
標籤:
上一篇:我需要一個更快的解決方案來對1對n相關表中具有多個特定匹配的表執行Select
下一篇:減去按列分組的2列
