SELECT GROUP_CONCAT() 中的 (1 和 2)

SELECT WHERE (1 AND 2) IN GROUP_CONCAT()

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(但可以具有更多)属性的实体。

我不喜欢这种解决方法:

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

它returns:

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

那我只好用服务器语言爆了然后排除


此查询 returns 所有实体的行:

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)

您可以使用 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 table.
  • 如果 entity_property 中不允许重复对,则不需要 DISTINCT
  • 要获得更多属性,您需要更改 WHEREHAVING(其中“2”是您要匹配的事物的数量)。

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

上的索引

您可以使用条件 having 子句找到至少具有 property_ids 1、2 的 entity_id,并在其上获得 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;