[英]Selecting by two parameters from table
我有一個HTML表單,可以在URL地址中按作者查找一本書。
網址是這樣的: http : //mywebsite.com/books/?author=john+smith ,它會檢索我的書。
我的SQL看起來像這樣:
SELECT
doc_documents.id doc_id,
doc_documents.projection_isbd doc_isbd
FROM
doc_documents
LEFT JOIN doc_document_authors ON doc_document_authors.document_id = doc_documents.id
LEFT JOIN usr_users ON usr_users.id = doc_document_authors.user_id
WHERE
doc_documents.status = 'CONFIRMED' AND
db_type = 'PDB' AND
deleted = 'f' AND
usr_users.title ilike $1
ORDER BY
doc_documents.publish_date desc
其中$ 1參數來自PHP腳本,而我從URL GET參數中提取。
問題是我試圖在URL中找到兩個(或更多)作者的書,即:
http://mywebsite.com/books/?author=john+smith&author2=william+lother
我試過這樣的SQL:
SELECT
doc_documents.id doc_id,
doc_documents.projection_isbd doc_isbd
FROM
doc_documents
LEFT JOIN doc_document_authors ON doc_document_authors.document_id = doc_documents.id
LEFT JOIN usr_users ON usr_users.id = doc_document_authors.user_id
WHERE
doc_documents.status = 'CONFIRMED' AND
db_type = 'PDB' AND
deleted = 'f' AND
(usr_users.title ilike $1 AND
usr_users.title ilike $2)
ORDER BY
doc_documents.publish_date desc
但它行不通。 你能幫我寫一個sql嗎?
你可以這樣嘗試嗎?
SELECT
doc_documents.id doc_id,
doc_documents.projection_isbd doc_isbd
FROM
doc_documents
LEFT JOIN doc_document_authors ON doc_document_authors.document_id = doc_documents.id
LEFT JOIN usr_users ON usr_users.id = doc_document_authors.user_id
WHERE
doc_documents.status = 'CONFIRMED' AND
db_type = 'PDB' AND
deleted = 'f' AND
(usr_users.title ilike $1) OR
(usr_users.title ilike $2)
ORDER BY
doc_documents.publish_date desc
不是嗎
(usr_users.title ilike $1 OR usr_users.title ilike $2)
代替
(usr_users.title ilike $1 AND usr_users.title ilike $2)
?
不僅僅是因為LIKE
和ILIKE
參數必須用%
字符括起來才能匹配字符串的一部分嗎? 您也可以嘗試使用正則表達式匹配運算符~
和~*
(用於不區分大小寫的搜索),它不必使用%
進行匹配
WHERE (usr_users.title ~* $1) AND (usr_users.title ~* $2)
注意: deleted
字段應為boolean或timestamptz而不是無用的char,SQL查詢以這種方式更具表現力:
WHERE … AND NOT deleted AND …
WHERE … AND deleted_at IS NOT NULL AND …
WHERE … AND NOT deleted AND …
(布爾值)或WHERE … AND deleted_at IS NOT NULL AND …
(timestamptz)。
您期望單個用戶的名稱(標題)與2個(或更多個)模式匹配; 這將不會發生(除非模式在某種程度上彼此相似)。
您需要做的(通常)是加入不同的用戶(他們當然是不同的作者)並分別過濾它們:
SELECT doc_documents.id doc_id,
doc_documents.projection_isbd doc_isbd
FROM doc_documents
JOIN doc_document_authors author1 ON author1.document_id = doc_documents.id
JOIN doc_document_authors author2 ON author2.document_id = doc_documents.id
JOIN usr_users user1 ON user1.id = author1.user_id
JOIN usr_users user2 ON user2.id = author2.user_id
WHERE doc_documents.status = 'CONFIRMED'
AND db_type = 'PDB'
AND NOT deleted
AND (user1.title ilike $1 AND user2.title ilike $2)
ORDER BY doc_documents.publish_date desc
當然,當您必須進行N次過濾時,很難一概而論。
另一種可能性是在聚合中使用一些bool_or()
:
SELECT doc_documents.id doc_id,
doc_documents.projection_isbd doc_isbd
FROM doc_documents
JOIN doc_document_authors ON doc_document_authors.document_id = doc_documents.id
JOIN usr_users ON usr_users.id = doc_document_authors.user_id
WHERE doc_documents.status = 'CONFIRMED'
AND db_type = 'PDB'
AND NOT deleted
GROUP BY doc_documents.id -- this will only work when id is the primary key
-- otherwise use the primary key of doc_documents
-- or doc_documents.*
HAVING bool_or(usr_users.title ilike $1)
AND bool_or(usr_users.title ilike $2)
ORDER BY doc_documents.publish_date desc
這將確保在每個文檔的所有作者中,每個usr_users.title ilike $N
表達式的usr_users.title ilike $N
都是true
(至少1次)。
還要注意,因為您在WHERE
過濾usr_users
,所以沒有必要使用LEFT JOIN
-您的過濾器仍然會強制執行INNER JOIN
(或簡稱JOIN
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.