SQL Select 从多对一
SQL Select from many-to-one
我有两个包含一对多关系的 table。我应该如何 select “一”方给出“多”方的信息?我正在使用 SQLite.
假设我们的第一个 table,T1,是关于汽车的,第二个 table,T2,是关于每辆车的缺陷。
假设我们可以用一个整数来描述缺陷。
所以我们有:
CREATE TABLE T1 (
id INTEGER PRIMARY KEY,
[Other columns]
);
CREATE TABLE T2 (
carId INTEGER REFERENCES T1(id),
imperfection INTEGER
);
我们有几辆汽车的数据,每辆都有很多缺陷。
给定一个表示缺陷的整数列表,我如何 select 汽车完全具有这组缺陷?例如,假设我有 [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, 5, 7)
group by carid
having count(*) = 3;
您可以使用聚合:
select carId
from t2
where imperfection in (1, 5, 7)
group by carId
having count(*) = 3
这带来了具有所有 3 个缺陷的汽车。如果您还想排除具有其他缺陷的汽车,则:
select carId
from t2
group by carId
having
sum(imperfection in (1, 5, 7)) = 3
and sum(imperfection not in (1, 5, 7)) = 0
如果您有像 '1,5,7'
这样以逗号分隔的排序字符串形式的缺陷列表,那么您可以使用 group_concat()
window 函数来完成:
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,5,7'
查看简化版 demo.
我有两个包含一对多关系的 table。我应该如何 select “一”方给出“多”方的信息?我正在使用 SQLite.
假设我们的第一个 table,T1,是关于汽车的,第二个 table,T2,是关于每辆车的缺陷。
假设我们可以用一个整数来描述缺陷。
所以我们有:
CREATE TABLE T1 (
id INTEGER PRIMARY KEY,
[Other columns]
);
CREATE TABLE T2 (
carId INTEGER REFERENCES T1(id),
imperfection INTEGER
);
我们有几辆汽车的数据,每辆都有很多缺陷。
给定一个表示缺陷的整数列表,我如何 select 汽车完全具有这组缺陷?例如,假设我有 [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, 5, 7)
group by carid
having count(*) = 3;
您可以使用聚合:
select carId
from t2
where imperfection in (1, 5, 7)
group by carId
having count(*) = 3
这带来了具有所有 3 个缺陷的汽车。如果您还想排除具有其他缺陷的汽车,则:
select carId
from t2
group by carId
having
sum(imperfection in (1, 5, 7)) = 3
and sum(imperfection not in (1, 5, 7)) = 0
如果您有像 '1,5,7'
这样以逗号分隔的排序字符串形式的缺陷列表,那么您可以使用 group_concat()
window 函数来完成:
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,5,7'
查看简化版 demo.