Я использую реляционное деление с EAV, но мне нужно найти результаты в EAV, которые имеют некоторые классификации - PullRequest
1 голос
/ 19 марта 2010

У меня есть две таблицы:

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).

Учитывая мой текущий дизайн, есть ли способ, которым я могу расширить свой запрос, чтобы включить подписчиков, которые имеют ноль или более определенных атрибутов, и если у них действительно есть определенный атрибут, то он должен соответствовать критериям?

Или есть лучший способ составить таблицу, чтобы помочь в запросах?

Ответы [ 2 ]

0 голосов
/ 04 мая 2010
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) 
) 

я думаю, что это можно упростить

0 голосов
/ 19 марта 2010

Это даже проще, чем ваш оригинальный запрос.

В основном вы хотите добавить всех, кто соответствует критериям, но вычесть всех, у которых есть критерии, которые не соответствуют:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...