我的桌子:
問題
id: serial
content: text
標簽
id: serial
name: text
問題標簽
question_id integer
tag_id integer
我需要選擇帶有標簽“css”的所有問題,但不要從 jsonb_agg() 中洗掉 JSON 中的所有其他標簽。我有這個 SQL 查詢:
SELECT q.id,
jsonb_agg(to_jsonb(tags)) AS tags
FROM questions q
LEFT JOIN questions_tags qt ON qt.question_id = q.id
LEFT JOIN tags ON tags.id = qt.tag_id
WHERE tags.name = 'css'
GROUP BY q.id
ORDER BY id
LIMIT 20
;
WHERE tags.name = 'css'子句從結果中洗掉所有其他標簽!
id | tags
----- ---------------------------
3 | [{"id": 3, "name": "css"}]
5 | [{"id": 3, "name": "css"}]
13 | [{"id": 3, "name": "css"}]
57 | [{"id": 3, "name": "css"}]
此問題有其他標簽,但 WHERE 子句將其洗掉。如何避免?我需要這樣的結果:
id | tags
----- ------------------------------------------------------
3 | [{"id": 3, "name": "css"}, {"id": 5, "name": "html"}]
5 | [{"id": 3, "name": "css"}]
13 | [{"id": 3, "name": "css"}, {"id": 7, "name": "js"}]
57 | [{"id": 3, "name": "css"}]
uj5u.com熱心網友回復:
你似乎很接近。連接邏輯沒問題,但不是過濾子句中的標簽名稱where,您需要使用having子句來檢查給定問題的任何標簽是否與您的搜索引數匹配:
SELECT q.id, jsonb_agg(to_jsonb(t)) AS tags
FROM questions q
INNER JOIN questions_tags qt ON qt.question_id = q.id
INNER JOIN tags t ON t.id = qt.tag_id
GROUP BY q.id
HAVING bool_or(t.name = 'css')
ORDER BY id
LIMIT 20
這樣,只要組中的任何標簽匹配,就會保留所有標簽,而不僅僅是保留原始代碼中的匹配標簽。
對您的代碼的其他更改:
- 在任何地方使用表別名(它在 上丟失
tags) - 使用
inner joins 而不是left joins (你不需要后者)
uj5u.com熱心網友回復:
您應該首先在 sub select 中選擇 questions.id where tag.name = 'css' ,然后在 column.id 所在的周圍 SELECT 中執行 jsonb_agg() ( sub select where tag.name = 'css' )
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/530322.html
