选择所有子行都符合条件的父行

Posted

技术标签:

【中文标题】选择所有子行都符合条件的父行【英文标题】:select parent row where ALL children rows meet criterias 【发布时间】:2019-11-28 06:10:51 【问题描述】:

我有两个表格,ratescriteriascriterias 中的 parent_id 指 rates 中的 id。 我需要选择表条件中 ALL 子行 WHERE criteria_1 AND criteria_2 等于 NULL 的比率。 在下面的示例中,应仅选择统一费率

费率

id   |    name   
--------------------
1    |    summer rate        
2    |    flat rate        
3    |    student rate

条件

id   |   parent_id   |    criteria_1   |   criteria_2
------------------------------------------------------
1    |    1          |    523          |   563
2    |    1          |    null         |   null
3    |    2          |    null         |   null
4    |    2          |    null         |   null
5    |    3          |    777          |   null

我试过 NOT EXIST,但它返回一个孩子有两个空标准的任何比率

【问题讨论】:

你说你试过不存在,但我们看不到 【参考方案1】:

尝试将此subqueryinner join 一起使用。

select * from 
    (select * from rates where name = 'flat rate') t1
inner join 
    (select * from criterias where coalesce(criteria_1, 0) = 0 and coalesce(criteria_2, 0) = 0) t2
            on t2.parent_id = t1.id

【讨论】:

使用这样的子查询有什么好处吗?将条件放在where 子句中不是更干净吗?请注意,这可能(并且将会)返回重复的 rates,其中不需要 criterias【参考方案2】:

请查看以下查询,它应该可以工作。您需要比较 2 个结果集才能找到所有空子的比率。

SELECT
a.parent_id
FROM(
SELECT
  parent_id,
  COUNT(*) AS total_count
FROM criterias c
WHERE c. criteria_1 IS NULL AND c.criteria_2 IS NULL
GROUP BY 1
) a
INNER JOIN (
SELECT
  parent_id,
  COUNT(*) AS total_count
FROM criterias c
GROUP BY 1
)b ON a.parent_id = b.parent_id AND a.total_count = b.total_count

【讨论】:

【参考方案3】:

我会使用一些聚合函数和一个由parent_id 分组的having 子句。

如果每个parent_id 至少有一个非空值,则使用minmax 将返回一个数值,但如果只有null,则将返回null。所以只需要使用having min(<field>) is null 来找到只有null 值的parent_id

select * 
from rates r
where id in(
    select parent_id
    from criterias
    group by parent_id
    having min(criteria_1) is null 
    and min(criteria_2) is null
);

或使用内部连接(如果您愿意)

select * 
from rates r
inner join (
    select parent_id
    from criterias
    group by parent_id
    having min(criteria_1) is null 
    and min(criteria_2) is null
) c ON c.parent_id = r.id;

验证:

create table rates(
    id int,
    name varchar(20)
);

create table criterias (
    id int,
    parent_id int,
    criteria_1 int null,
    criteria_2 int null
);

insert into rates values (1, 'summer rate');
insert into rates values (2, 'flate rate');
insert into rates values (3, 'student rate');
insert into rates values (4, 'old rate');
insert into rates values (5, 'any rate');

insert into criterias values (1, 1, 523, 563);
insert into criterias values (2, 1, null, null);
insert into criterias values (3, 2, null, null);
insert into criterias values (4, 2, null, null);
insert into criterias values (5, 1, 777, null);
insert into criterias values (6, 4, null, null);
insert into criterias values (7, 5, null, null);
insert into criterias values (8, 5, null, null);
/*insert into criterias values (9, 5, 1, null);*/

select * 
from rates r
where id in(
    select parent_id
    from criterias
    group by parent_id
    having min(criteria_1) is null 
    and min(criteria_2) is null
);

结果:

id  name
2   flate rate
4   old rate
5   any rate

【讨论】:

当一个子行的条件_1 和条件_2 等于 NULL 时,两个查询都返回所有父项 @user1709251 我的错,没有抓住粗体部分......这样就可以了 @user1709251 已更新。验证脚本显示一个注释行,添加该行将从结果中删除 any rate

以上是关于选择所有子行都符合条件的父行的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:如何将子项的 SUM() 值更新为同一表中的父行?

SQL从每个父行的子行返回最大值

jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器

HTML:如何使用 AngularJs 填充第一行是父行和后续行是子行的行

jQuery tablesorter 仅对子行分组小计

剑道网格 - 如何在添加/编辑子行时访问父行模型(详细网格)