从表中选择两个参数

时间:2016-10-24 12:21:57

标签: php postgresql

我有一个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吗?

4 个答案:

答案 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)

是不是因为LIKEILIKE参数必须包含在%字符中以匹配字符串的一部分?您还可以尝试使用正则表达式匹配运算符~~*(对于不区分大小写的搜索),它不必使用%来匹配

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总之,无论如何。