MySQL JOIN语句按选定的链接属性过滤行

时间:2015-11-11 00:54:24

标签: mysql join

假设我有以下两个MySQL表:

item: _ID,_CAT_ID,...

item_attribute:     _ID,_ITEM_ID,...

我想(过滤商品)仅获取具有所有所选属性的项目(1,32,555,......所选属性的数组)

类似的东西:

SELECT  _I.* 
FROM  item _I
INNER JOIN item_attribute _IA
ON (_I._ID = _IA._ITEM_ID AND (_IA._ID=1 OR _IA._ID=132, ...))
WHERE _I._CAT_ID=? ORDER BY _I._LAST_UPDATE ASC;"

这个“错误”语句在找到链接ID的一个(由于OR)时返回项目,我想要的是:只有具有所有链接属性的项目。

如果我改变

(_IA._ID=1 OR _IA._ID=132 OR...) 

(_IA._ID=1 AND _IA._ID=132 AND ...)

没有匹配,这是有道理的,但如何重写语句以获得正确的匹配?

更新

这是一个sqlfiddle:http://sqlfiddle.com/#!9/0f8ebe/6

CREATE TABLE item
    (`id` int, `pid` int, `name` varchar(55))
;

INSERT INTO item
    (`id`, `pid`, `name`)
VALUES
    (1, 2, 'A'),
    (2, 2, 'B'),
    (3, 2, 'C')
;
CREATE TABLE att
    (`id` int, `pid` int, `name` varchar(55))
;

INSERT INTO att
    (`id`, `pid`, `name`)
VALUES
    (7, 1, 'red'),
    (7, 3, 'red'),
    (2, 1, '30cm'),
    (1, 3, '40cm'),
    (5, 2, 'blue'),
    (1, 2, '40cm')
;
SELECT * 
FROM  item;

SELECT * 
FROM  att;

/* expected: items which are red AND 40cm, result should be then only item C (id=3)*/

SELECT  _I.name 
FROM  item _I
INNER JOIN att _IA
ON (_I.id = _IA.pid AND (_IA.id=7 AND _IA.id=1))
WHERE _I.pid=2 GROUP BY _I.id;

解决方案http://sqlfiddle.com/#!9/0f8ebe/8(使用Drews答案):

SELECT  _I.name,count(_IA.id) as theCount 
FROM  item _I
INNER JOIN att _IA
ON (_I.id = _IA.pid) AND _IA.id in (7,1)
WHERE _I.pid=2
group by _I.id
having theCount=2

2 个答案:

答案 0 :(得分:1)

它应该带来所有具有3个特定项目属性的项目(红色,40cm,大)。

SQL Fiddle

SELECT kk.*
FROM item AS kk
INNER JOIN (
    SELECT aa.id
    FROM (
        SELECT DISTINCT bb.id
        FROM item AS bb
        INNER JOIN att AS cc 
        ON bb.id = cc.pid
        WHERE cc.name IN ('red', '40cm', 'large')
        GROUP BY bb.id 
        HAVING COUNT(*) = 3
    ) AS aa
) AS _aa
ON kk.id = _aa.id;

结果:

id  pid name
3   2   C

答案 1 :(得分:1)

我认为这是7行代码,从你的问题中读取花絮:

SELECT  _I.col1,_I.col2,count(_IA._ID) as theCount 
FROM  item _I
INNER JOIN item_attribute _IA
ON (_I._ID = _IA._ITEM_ID) AND _IA._ID in (1,32,555)
WHERE _I._CAT_ID=? ORDER BY _I._LAST_UPDATE ASC
group by _I.col1,_I.col2
having theCount=3

请注意,theCount子句中允许使用having别名。

另请注意,我在第一行放入col1和col2,相应地展开。关键是列出它们,因此第6行中的group by可以模仿非聚合列。第7行中的值必须与clause

中的值的计数相匹配