我有3个postgresql表:文档,关键字和连接表。
我有查询,如果某些关键字与该文档相关,则会搜索document.id和document.date。这样做很好:
SELECT
documents.id, documents.document_date
FROM
documents
INNER JOIN
documents_keywords ON documents_keywords.document_id = documents.id
INNER JOIN
keywords ON keywords.id = documents_keywords.keyword_id
WHERE
keywords.keyword IN ('bread' , 'cake')
GROUP BY documents.id
返回:
id | document_date
----+-----------
4 | 1200
12 | 1280
(2 rows)
我还想排除关键字。我以为我可以这样做NOT IN
:
SELECT
documents.id, documents.document_date
FROM
documents
INNER JOIN
documents_keywords ON documents_keywords.document_id = documents.id
INNER JOIN
keywords ON keywords.id = documents_keywords.keyword_id
WHERE
keywords.keyword NOT IN ('cranberries')
GROUP BY documents.id
但是,无论我放置什么关键字,它总是返回空白:
id | document_date
----+-----------
(0 rows)
这是不正确的。我期待:
id | document_date
----+-----------
4 | 1200
(1 row)
答案 0 :(得分:0)
您可能想要使用数组表达式,如下所示:
WHERE keyword = any(array['bread', 'cake'])
当你想要包含一行时。
如果要排除某些内容,则必须在反向条件的子选择中执行NOT IN,例如
SELECT ... WHERE document_id NOT IN
(SELECT document_id FROM ...joins... WHERE keyword = ANY(array['cranberry']))
这是我放在一起的一个例子:
WITH documents(d_id, date) AS (
VALUES(1,'1000'),(2,'2000'),(3,'3000'),(4,'4000')
),
keywords(k_id, keyword) AS (
VALUES(1, 'cake'), (2, 'bread'), (3, 'cranberry')
),
documents_keywords (d_id, k_id) AS (
VALUES(1,1),(1,2),(2,2),(2,3),(3,3)
)
SELECT * FROM documents where d_id NOT IN (
SELECT d_id FROM
documents
JOIN documents_keywords USING(d_id)
JOIN keywords USING(k_id)
WHERE keyword = ANY(array['cranberry'])
)
此外,我不确定您使用GROUP BY
的原因,我认为您不需要它。