SQL多对一选择

问题描述

我有两个包含一对多关系的表。我应该如何为“许多”方面选择给定信息的“一个”方面?我正在使用SQLite

假设我们的第一个表T1是关于汽车的,而第二个表T2是关于每辆汽车的缺陷的。

让我们用一个整数来描述缺陷。

所以我们有:

formatter

我们有一些汽车的数据,每辆汽车都有很多缺陷。

给出代表缺陷的整数列表,我该如何选择恰好具有这组缺陷的汽车?例如,假设我有[1,5,7]作为缺陷列表,我如何找出与19号车匹配的东西?

如果有帮助,我希望每组唯一的瑕疵都只有一个匹配项。

这个问题与DBA Stack Exchange question中的问题类似,但是在前面的问题中,缺陷的数量是已知的。在这个问题上,我不知道缺陷的数量

解决方法

您可以使用条件聚合。假设您没有重复项:

select carid
from t2
group by carid
having sum(case when imperfection in (1,5,7) then 1 else 0 end) = 3;

这仅查找具有精确的1、5和7的汽车。如果您想要任何具有这些特征的汽车,也许还有其他汽车,则可以简化为:

select carid
from t2
where imperfection in (1,7)
group by carid
having count(*) = 3;
,

您可以使用聚合:

select carId
from t2
where imperfection in (1,7)
group by carId
having count(*) = 3

这带来了具有所有3个缺陷的汽车。如果您也要排除其他缺陷的汽车,则:

select carId
from t2
group by carId
having
    sum(imperfection in (1,7)) = 3
    and sum(imperfection not in (1,7)) = 0

,

如果缺陷列表以逗号分隔的字符串形式出现,例如'1,7',则可以使用group_concat()窗口函数:

select carId
from (
  select *,row_number() over (partition by carId order by imperfection desc) rn,group_concat(imperfection) over (partition by carId order by imperfection) imperfections
  from T2
)   
where rn = 1 and imperfections = '1,7'

查看简化的demo