查询多个表,但只从一个表中获取结果而不重复

时间:2012-06-03 16:04:23

标签: mysql sql join

这是一个解释我需要的例子:

我有3张桌子:

 contact: { id, invoices, name } // a contact can have several invoices
 invoice: { id, contact, lines, comment } // an invoice can have several lines but only one contact
 line: { id, invoice, designation } // a line can have only one invoice

如果用户搜索发票,则想要查询评论,指定和名称字段,并仅获取匹配的发票。

所以我做到了这一点:

SELECT 
  invoice.id AS id, 
  invoice.contact AS contact, 
  invoice.comment AS comment, 
FROM invoice 
  LEFT JOIN contact ON invoice.contact = contact.id 
  LEFT JOIN line ON line.invoice = invoice.id
WHERE (
  contact.name LIKE '%SEARCH_TERM%' OR 
  invoice.comment LIKE '%SEARCH_TERM%' OR 
  line.designation LIKE '%SEARCH_TERM%'
)

这项工作除了如果发票有几行与搜索字词匹配,我会得到相同发票的几倍。

所以我的问题是:即使在几个相关记录中找到搜索词,是否有办法只获得一次发票?

另外,有没有办法只使用发票的字段而不使用ALIAS(除了搜索,我不关心表格的联系和行)?

如果你知道更好的方法,我很乐意听到它。

3 个答案:

答案 0 :(得分:1)

SELECT 
  DISTINCT invoice.*
FROM invoice 
  LEFT JOIN contact ON invoice.contact = contact.id 
  LEFT JOIN line ON line.invoice = invoice.id
WHERE (
  contact.name LIKE '%SEARCH_TERM%' OR 
  invoice.comment LIKE '%SEARCH_TERM%' OR 
  line.designation LIKE '%SEARCH_TERM%'
)

答案 1 :(得分:1)

是。您可以通过向WHERE子句添加子查询来执行此操作:

SELECT invoice.id AS id, invoice.contact AS contact, invoice.comment AS comment, 
FROM invoice LEFT JOIN
     contact
     ON invoice.contact = contact.id 
WHERE contact.name LIKE '%SEARCH_TERM%' OR 
      invoice.comment LIKE '%SEARCH_TERM%' OR
      invoice.id in (select line.invoice
                     from line
                     where line.designation LIKE '%SEARCH_TERM%')

您还可以使用子查询在FROM子句中构造它:

SELECT invoice.id AS id, invoice.contact AS contact, invoice.comment AS comment, 
FROM invoice LEFT JOIN
     contact
     ON invoice.contact = contact.id left join
     (select distinct line.invoice
      from line
      where line.designation LIKE '%SEARCH_TERM%'
     ) line
     on line.invoice = invoice.id
WHERE contact.name LIKE '%SEARCH_TERM%' OR 
      invoice.comment LIKE '%SEARCH_TERM%' OR
      line.invoice is not null

在此构造中,如果多行包含搜索词,则需要distinct关键字以防止重复行。

答案 2 :(得分:0)

DISTINCT会起作用吗?

SELECT DISTINCT
  i.id, 
  i.contact, 
  i.comment, 
FROM invoice AS i
  LEFT JOIN contact ON i.contact = contact.id 
  LEFT JOIN line ON line.invoice = i.id
WHERE (
  contact.name LIKE '%SEARCH_TERM%' OR 
  i.comment LIKE '%SEARCH_TERM%' OR 
  line.designation LIKE '%SEARCH_TERM%'
)