2017-01-21 70 views
0

我需要帮助,我必须对连接表有一些基本的误解。我有3个表格,'item','property','propvalues' 我尝试列举颜色为黑色或灰色,而形状为圆形的项目,例如。 (我的表是比较复杂的,我只是试图让简单的现在。)Mysql查询连接表问题

item 
id  category_id 
1   1 
2   1 
3   2 
4   3 

property 
id   name 
    1   'shape' 
    2   'color' 

propvalues 
id   property_id  item_id value 
1   1    1   'round' 
2   2    1   'grey' 
3   1    2   'round' 
4   2    2   'black' 
5   1    3   'square' 
6   2    3   'black' 

我有这个疑问:

SELECT item.id FROM item 
JOIN propvalues ON item.id=propvalues.item_id 
WHERE item.category_id IN (1,2) && 
propvalues.value IN ('black','grey') AND propvalues.value IN ('round') 

,但是这给了我没有结果,而它应该输出项目id 1和2 (因为它们都是圆的,其中一个是灰色的,另一个是黑色的。) (我也想在where子句中包含property_id,因为后面不同的属性可能有相同的propvalues.value,所以实际上where子句将如下所示:)

WHERE item.category_id IN(1,2) && 
(propvalues.property_id = 2 && propvalues.value IN ('black','grey')) && 
(propvalues.property_id = 1 && propvalues.value IN ('round')) 

有人能告诉我为什么不给我想要的结果吗?请解释我什么是对

+0

你为什么要使用像 propvalues.value IN(“黑”,“灰色”)AND propvalues.value IN('round')??? 您应该使用 propvalues.value IN('black','gray','round') –

+0

因为这种情况下,我会列出每件黑色或灰色或圆形的物品。但我想要的只是那些圆形的,黑色的或灰色的。另外,因为未来如果我拥有像('内部尺寸'和'外部尺寸')这样的属性并且属性值对于两者都是相同的,例如内部尺寸:25毫米,外部尺寸:25毫米,比我会得到不好的结果。 – Ninet9

+0

显示您想要的输出。 – denny

回答

0

这里有几个基本的想法......玩弄

DROP TABLE IF EXISTS eav; 

CREATE TABLE eav 
(entity INT NOT NULL 
,attribute INT NOT NULL 
,value VARCHAR(20) NOT NULL 
,PRIMARY KEY(entity,attribute) 
); 

INSERT INTO eav VALUES 
(1,1,'round'), 
(1,2,'grey'), 
(2,1,'round'), 
(2,2,'black'), 
(3,1,'square'), 
(3,2,'black'); 

SELECT x.entity 
    , MAX(CASE WHEN x.attribute = 1 THEN x.value END) shape 
    , MAX(CASE WHEN x.attribute = 2 THEN x.value END) colour 
    FROM eav x 
GROUP 
    BY x.entity 
HAVING shape IN('round') 
    AND colour IN('black','grey'); 

    +--------+-------+--------+ 
    | entity | shape | colour | 
    +--------+-------+--------+ 
    |  1 | round | grey | 
    |  2 | round | black | 
    +--------+-------+--------+ 

SELECT x.entity 
    , shape.value shape 
    , colour.value colour 
    FROM eav x 
    LEFT 
    JOIN eav shape 
    ON shape.entity = x.entity 
    AND shape.attribute = 1 
    LEFT 
    JOIN eav colour 
    ON colour.entity = x.entity 
    AND colour.attribute = 2; 

+--------+--------+--------+ 
| entity | shape | colour | 
+--------+--------+--------+ 
|  1 | round | grey | 
|  1 | round | grey | 
|  2 | round | black | 
|  2 | round | black | 
|  3 | square | black | 
|  3 | square | black | 
+--------+--------+--------+ 
+0

这看起来不像我的db表 – Ninet9

+0

@ Ninet9它看起来很像你的表。并且具有作为一组CREATE和INSERT语句提供的独特优势。 – Strawberry

+0

谢谢草莓。我做了一些研究,如何工作,我可以使用这些想法。 – Ninet9

0

要去你有互斥WHERE条件:

propvalues.value IN ('black','grey') AND propvalues.value IN ('round') 

相同的值不能同时'round''round'。同样的问题,你以后的例子:

(propvalues.property_id = 2 && [...]) && 
(propvalues.property_id = 1 && [...]) 

相同的值不能同时21

由于任何一条记录都不可能满足WHERE条件,因此不会返回任何记录。

根据所需结果的描述,听起来好像您想要在AND条件的分组之间使用OR条件。事情是这样的:

(propvalues.property_id = 2 AND propvalues.value IN ('black','grey')) OR 
(propvalues.property_id = 1 AND propvalues.value IN ('round')) 
+0

除了我怀疑op需要满足条件 – Strawberry

+0

(propvalues.property_id = 2 AND propvalues.value IN('black','gray'))的行或者 (propvalues.property_id = 1 AND propvalues.value IN('round'))。那种情况下,如果我理解正确,它会给我所有黑色或灰色或圆形的物品。但我需要的是黑色或灰色的物品,也是两个圆形 – Ninet9

+0

@Strawberry:好吧,因为没有行可以满足这两个条件,从技术上讲这就是OP已经得到的东西。 – David