1

我有两张桌子:

CREATE TABLE `EAV` (  
  `subscriber_id` INT(1) NOT NULL DEFAULT '0',   
  `attribute_id` CHAR(62) NOT NULL DEFAULT '',  
  `attribute_value` CHAR(62) NOT NULL DEFAULT '',  
  PRIMARY KEY  (`subscriber_id`,`attribute_id`)  
) 

INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (1,'color','red')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (1,'size','xl')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (1,'garment','shirt')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (2,'color','red')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (2,'size','xl')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (2,'garment','pants')  
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (3,'garment','pants')  

CREATE TABLE `CRITERIA` (  
  `attribute_id` CHAR(62) NOT NULL DEFAULT '',  
  `attribute_value` CHAR(62) NOT NULL DEFAULT '' 
)   

INSERT INTO CRITERIA (attribute_id, attribute_value) VALUES ('color', 'red')  
INSERT INTO CRITERIA (attribute_id, attribute_value) VALUES ('size', 'xl')  

为了在 EAV 中查找符合我的条件的所有订阅者,我使用了关系除法:

SELECT DISTINCT(subscriber_id)  
 FROM EAV  
 WHERE subscriber_id IN  
 (SELECT E.subscriber_id FROM EAV AS E   
 JOIN CRITERIA AS CR ON E.attribute_id = CR.attribute_id AND E.attribute_value =   CR.attribute_value  
 GROUP BY E.subscriber_id  
 HAVING COUNT(`*`) = (SELECT COUNT(`*`) FROM CRITERIA))   

这为我提供了具有所有标准的唯一订阅者列表。所以这意味着我会找回订阅者 1 和 2,因为他们正在寻找红色和 xl 尺寸,而这正是我的标准。

但是如果我想扩展它以便我也得到订阅者 3,因为这个订阅者没有具体说明他们想要什么颜色或大小(即 EAV 表中没有属性“颜色”或“大小”的条目订户 3)。

鉴于我目前的设计,有没有一种方法可以扩展我的查询以包括定义了零个或多个属性的订阅者,如果他们确实定义了属性,那么它必须匹配标准?

还是有更好的方法来设计表格以帮助查询?

4

2 回答 2

0
SELECT DISTINCT(E.subscriber_id) FROM EAV AS E 
LEFT JOIN CRITERIA AS CR ON (E.attribute_id = CR.attribute_id AND E.attribute_value = E.attribute_value) 
WHERE subscriber_id NOT IN ( 
SELECT subscriber_id FROM EAV AS E 
JOIN CRITERIA AS CR ON (E.attribute_id = CR.attribute_id AND E.attribute_value <> CR.attribute_value) 
) 

我认为这可以简化

于 2010-05-04T03:23:02.140 回答
0

它甚至比您的原始查询更容易。

您基本上想添加符合条件的每个人,但减去具有不匹配条件的每个人:

SELECT DISTINCT(E.subscriber_id) FROM EAV AS E
LEFT JOIN CRITERIA AS CR ON (E.attribute_id = CR.attribute_id AND E.attribute_value = E.attribute_value)
WHERE subscriber_id NOT IN (
SELECT subscriber_id FROM EAV AS E
JOIN CRITERIA AS CR ON (E.attribute_id = CR.attribute_id AND E.attribute_value <> CR.attribute_value)
)

为了测试,我添加了更多记录:

INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (4,'color','blue');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (4,'garment','shirt');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (5,'color','blue');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (5,'size','xl');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (5,'garment','shirt');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (6,'color','red');
INSERT INTO EAV (subscriber_id, attribute_id, attribute_value) VALUES (6,'garment','shirt');

查询返回:

1
2
3
6
于 2010-03-19T20:41:35.927 回答