1

私は2つのテーブルを持っています:

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 も取得するようにしたい場合はどうでしょう。サブスクライバー 3)。

現在の設計を考えると、クエリを拡張して、0 個以上の属性が定義されているサブスクライバーを含める方法はありますか?また、属性が定義されている場合は、基準に一致する必要がありますか?

または、クエリを支援するためにテーブルを設計するより良い方法はありますか?

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

テストするために、さらにいくつかのレコードを追加しました。

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 に答える
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 に答える