Mysql Join Query多次提供相同的结果

时间:2010-02-22 16:44:24

标签: php mysql

我有两张桌子。一个是items,一个是tags。查询here

我们的想法是创建一个搜索框来搜索项目,然后通过选择标签缩小搜索范围。 (某种分面搜索)。

在摆弄了mysql教程后,我想出了这个:

SELECT `items`.`id`, `items`.`name`, `items`.`pay`, `items`.`desc`
FROM `items`LEFT JOIN (`tags`) ON (`tags`.`item_id`=`items`.`id`) 
WHERE (
    (`tags`.`type`='food' AND `tags`.`name`='pizza')
    OR (`tags`.`type`='drinks' AND `tags`.`name`='lemonade')
    --And so on for every tag
)
ORDER BY `pay` DESC LIMIT 0 , 30

(我删除了查询中的全文搜索,因为它现在不相关)

它工作得很好,但我有两个问题:

  1. 如果用户没有选择任何标签,那么附加了超过1个标签的每个项目都会显示超过1次
  2. 如果用户选择两个标签,例如food => pizza和drink =>柠檬水,那么每个带有披萨或柠檬水或两者的商品都会显示出来,我只想要那些附有这些标签的商品。
  3. 是否可以使用不同的mysql查询解决这些问题?或者我应该在PHP代码中修复这些问题。 (或者我完全错了,是否有更好的方法来使用标签?)

    希望我能说清楚。

    GR,

    BAS

2 个答案:

答案 0 :(得分:2)

在SELECT?

之后输入关键字DISTINCT
SELECT DISTINCT `items`.`id`, `items`.`name`, `items`.`pay`, `items`.`desc` 
FROM `items`LEFT JOIN (`tags`) ON (`tags`.`item_id`=`items`.`id`)  
WHERE ( 
    (`tags`.`type`='food' AND `tags`.`name`='pizza') 
    OR (`tags`.`type`='drinks' AND `tags`.`name`='lemonade') 
    --And so on for every tag 
) 
ORDER BY `pay` DESC LIMIT 0 , 30 

至于你的第二个问题......你的逻辑是错的。如果我理解你正确你想按items.id分组,然后拒绝没有返回的项目与所选标签的数量相同的行数...可能是这样的:

SELECT DISTINCT `items`.`id`, `items`.`name`, `items`.`pay`, `items`.`desc` 
    FROM `items`LEFT JOIN (`tags`) ON (`tags`.`item_id`=`items`.`id`)  
    WHERE ( 
        (`tags`.`type`='food' AND `tags`.`name`='pizza') 
        OR (`tags`.`type`='drinks' AND `tags`.`name`='lemonade') 
        --And so on for every tag 
    ) 
    GROUP BY `items`.`id` 
    HAVING COUNT(*) = 2 
    ORDER BY `pay` DESC LIMIT 0 , 30 

...并将HAVING COUNT(*)= 2中的2替换为您尝试同时匹配的标签数量...

答案 1 :(得分:1)

尝试WHERE tag.id IN(SUBQUERY)

SELECT `items`.`id`, `items`.`name`, `items`.`pay`, `items`.`desc`
FROM `items`  WHERE items.id IN (SELECT DISTINCT item_id
   FROM tags
   WHERE (
    (`tags`.`type`='food' AND `tags`.`name`='pizza')
    OR (`tags`.`type`='drinks' AND `tags`.`name`='lemonade'))
    --And so on for every tag
)
ORDER BY `pay` DESC LIMIT 0 , 30