我有一个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参数中删除。
问题在于我试图在网址中找到两位(或更多)作者的书籍,i。 E:
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吗?
答案 0 :(得分:1)
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
答案 1 :(得分:1)
不应该
(usr_users.title ilike $1 OR usr_users.title ilike $2)
而不是
(usr_users.title ilike $1 AND usr_users.title ilike $2)
答案 2 :(得分:0)
是不是因为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 …
(timestamptz)。
答案 3 :(得分:0)
您希望将单个用户的姓名(标题)与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
表达式(至少1次)true
。
另请注意,由于您在usr_users
中过滤了WHERE
,因此无法使用LEFT JOIN
- 您的过滤器会强制INNER JOIN
(或{{1总之,无论如何。