2017-01-09 65 views
0
entity 
--- 
id name 
--- 
1 one 
2 two 
3 three 

property 
--- 
id name 
--- 
1 prop1 
2 prop2 
3 prop3 

entity_property 
--- 
entity_id property_id 
--- 
1   1 
1   2 
1   3 
2   1 

我想獲得至少有1和2(但可以有更多)屬性的實體。選擇哪裏(1和2)在GROUP_CONCAT()

這是一種解決方法,我不喜歡:

SELECT entity_property.entity_id, 
(GROUP_CONCAT(entity_property.property_id)) as props 
FROM `entity_property` 
JOIN entity 
ON entity_property.entity_id = entity.id 
GROUP BY entity.id 

它返回:

entity_id props 
--- 
1 1,2,3 
2 1 

然後我有服務器的語言爆發,然後排除。


該查詢返回所有實體的行:

SELECT entity.id 
FROM entity 
WHERE (1 AND 2) IN 
    (SELECT property_id 
    FROM entity_property 
    LEFT JOIN entity 
    ON entity_property.entity_id = entity.id 
    WHERE entity_property.entity_id = entity.id) 

此查詢導致錯誤:

SELECT entity.id as ent_id 
FROM entity 
WHERE (1 AND 2) IN 
    (SELECT property_id 
    FROM entity_property 
    LEFT JOIN entity 
    ON entity_property.entity_id = entity.id 
    WHERE entity_property.entity_id = ent_id) 
+1

見http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-一個非常簡單的sql查詢 - 但我不回答包含單詞'想'的問題 - 這只是一個規則。 – Strawberry

回答

0

可以使用group byhaving得到實體ID:

SELECT ep.entity_id 
FROM `entity_property` ep 
WHERE ep.property_id IN (1, 2) 
GROUP BY ep.entity_id 
HAVING COUNT(DISTINCT ep.property_id) = 2; 

注:

  • 這不需要entity表。
  • 如果在entity_property中不允許有重複對,則不需要DISTINCT
  • 更多的屬性,您需要更改打擾WHEREHAVING(其中「2」是的東西,你想匹配的數量)。
+0

很好,我明白了! – Xitroff

0

您有興趣從entity那些在entity_property與1或2的值記錄的所有記錄要做到這一點,你可以只用內部的一個限制因素加入entity_property,例如

SELECT 
    e.* 
FROM entity e 
INNER JOIN entity_property ep1 
    ON ep1.entity_id = e.id 
    AND ep1.property_id = 1 
INNER JOIN entity_property ep2 
    ON ep2.entity_id = e.id 
    AND ep2.property_id = 2 

內部連接確保只有來自entity的記錄返回entity_property中的對應行。雙連接可以讓您確保entity行同時擁有1和2。使用簡單連接允許使用索引,例如在entity_property (property_id , entity_id)

0

索引可以找到使用條件有property_ids的ENTITY_ID ATLEAST 1,2有條款,並獲得該group_concat。

試試這個:

select entity_id, group_concat(property_id) 
from entity_property 
group by entity_id 
having 
count(distinct 
     case when property_id in (1, 2) 
     then property_id end) = 2;