2011-07-14 149 views
1

我对高级MySQL命令相当新颖,我有具有多个关系的数据库表。我有一个高级搜索功能,必须将关键字匹配到几个字段(大多数在资产表中,但在用户表中有一对)。当我为桌面执行以下查询时,它会多次返回相同的行,而它应该执行一次。SQL多次返回相同的结果

SELECT 
    a.id, a.asset_id, a.name, a.serial_number, a.category_id, a.status_id, a.user_id, a.location_id 
FROM 
    assets a, users u 
WHERE 
    (a.asset_ID LIKE '%desk%' OR a.name LIKE '%desk%' OR (u.first_name LIKE '%desk%' OR u.last_name LIKE '%desk%')) AND 
    a.serial_number LIKE '%%' AND 
    a.category_id='2' 
LIMIT 25 OFFSET 5450 
+0

可以粘贴输出的样本? – Yuck

+0

查询是否与单个行中的搜索关键字多次匹配?这可能会让你走上正轨 – Ryan

回答

9

您在查询中有cartesian product。您应该加入资产和用户,例如与

WHERE a.user_id = u.id 

或类似这样的

FROM assets a JOIN users u ON a.user_id = u.id 

UPDATE:您的评论表明你真的想 “左外连接” 用户表。这意味着,所有资产都在结果集不管是否存在匹配的用户:

FROM assets a LEFT OUTER JOIN users u ON a.user_id = u.id 

了解更多关于此连接表:http://dev.mysql.com/doc/refman/5.5/en/join.html

+0

请尽量选择后者。保持连接标准和选择标准分离使得更好的可读性。 – Yuck

+0

@Yuck:绝对。但是对于新手来说,一次只能迈出一步:-) –

+0

谢谢,这是它缺少的确切的东西。 –

0

你缺少两个表之间的连接。

添加类似

AND a.user_id = u.user_id 
1

你可以使用SELECT DISTINCT子句,尽管实际问题看起来像由卢卡斯做出的一个。最好使用如下所示的显式连接:

FROM assets a 
JOIN users u ON a.user_id=u.id 
+0

嗯,是的。 'DISTINCT'在这种情况下是正确的,没有'用户'的投影。你的DBA会杀了你;-) –

1

您需要将两个表(资产和用户)实际连接在一起。如你所知,每个表中的每一行都与另一行中的每一行相匹配。这被称为笛卡尔积,通常是一件坏事。

我也建议你开始使用正确的语法JOIN

SELECT 
    a.id, 
    a.asset_id, 
    a.name, 
    a.serial_number, 
    a.category_id, 
    a.status_id, 
    a.user_id, 
    a.location_id 
FROM 
    Assets A 
INNER JOIN Users U ON A.user_id = U.user_id 
WHERE 
    (
     a.asset_ID LIKE '%desk%' OR 
     a.name LIKE '%desk%' OR 
     (
      u.first_name LIKE '%desk%' OR 
      u.last_name LIKE '%desk%' 
     ) 
    ) AND 
    a.serial_number LIKE '%%' AND 
    a.category_id='2' 
LIMIT 25 
OFFSET 5450 
相关问题