Mysql 连接表并在第一个表中选择所有行都满足条件的外键
我有两张桌子 帐目Mysql 连接表并在第一个表中选择所有行都满足条件的外键,mysql,sql,compare,case,Mysql,Sql,Compare,Case,我有两张桌子 帐目 ID | Deleted? | Type 1 | 0 | Father 2 | 0 | Son 3 | 1 | Son 4 | 1 | Son 5 | 0 | Father 6 | 0 | Father 7 | 1 | Son 8 | 0 | Son 9 | 0 | Fathe
ID | Deleted? | Type
1 | 0 | Father
2 | 0 | Son
3 | 1 | Son
4 | 1 | Son
5 | 0 | Father
6 | 0 | Father
7 | 1 | Son
8 | 0 | Son
9 | 0 | Father
10 | 1 | Son
关系账户
ID | SON | FATHER
1 | 4 | 6
2 | 3 | 6
3 | 2 | 5
4 | 4 | 1
5 | 7 | 1
6 | 8 | 9
7 | 10 | 9
我只想选择活动的(已删除=0)父亲ID,这些父亲ID的儿子已删除=1:
FATHERS
6
1
当父亲=0,但他所有的儿子都删除=1时,你如何获得这些记录
我尝试了以下方法,但无效:
SELECT A.ID,
case when A.DELETED = 0
THEN (SELECT AH.SONS FROM ACCOUNTS_REL AH WHERE AH.FATHER = A.ID AND A.DELETED = 1)
END
FROM ACCOUNTS A
WHERE A.TYPE = 'Father'
预期结果为1和6,因为他们是活动父亲,并且他们的所有儿子都被删除。如果希望所有活动父亲的所有儿子都已删除,这等于说所有活动父亲都有儿子但没有活动儿子,请尝试以下操作:
select distinct rc.father
from accounts a
join rel_accounts rc on a.id=rc.father
where a.deleted=0
and rc.father not in
(select qrc.father
from accounts qa
join rel_accounts qrc on qa.id=qrc.father
where qa.deleted=0
and qrc.son in
(select qracc.son
from rel_accounts qracc
join accounts qacc on qracc.son=qacc.id
where qacc.deleted=0))
order by father desc
请参见在这种情况下,您需要使用多个联接来创建所需的数据集。如果我理解正确,您希望筛选出从结果集中删除的帐户记录,然后只返回表示有儿子的父亲的行。这样的东西应该足够了:
Select distinct F.id from accounts F
join rel_accounts R on R.father=F.id
join accounts S on S.id=R.son
where F.deleted=0 and S.deleted=0;
联接本身会过滤掉您不想要的结果,然后您可以简单地从结果集中排除已删除的行
其他人可能会为你准备一个稍微干净一点的版本。正如我一直建议的那样,把它分解成几部分,然后再重新组装起来 从获取活动父亲列表开始:
SELECT id
FROM accounts
WHERE deleted = 0 AND type = 'Father';
了解不活跃的儿子也很重要:
SELECT id
FROM accounts
WHERE deleted = 1 AND type = 'Son'
现在,只需从rel_accounts表中提取,其中父亲在第一个查询中,儿子在第二个查询中:
SELECT *
FROM rel_accounts
WHERE father IN(
SELECT id
FROM accounts
WHERE deleted = 0 AND type = 'Father')
AND son IN(
SELECT id
FROM accounts
WHERE deleted = 1 AND type = 'Son');
编辑我原以为这是解决方案,但测试后我意识到这并不能检查是否每个儿子都被删除。为此,我首先得到了每位父亲的儿子数量:
SELECT father, COUNT(*) AS numSons
FROM rel_accounts
GROUP BY father;
我使用相同的方法来获得每个活跃父亲删除的儿子数:
SELECT father, COUNT(*) AS numDeletedSons
FROM rel_accounts
WHERE father IN(
SELECT id
FROM accounts
WHERE deleted = 0 AND type = 'Father')
AND son IN(
SELECT id
FROM accounts
WHERE deleted = 1 AND type = 'Son')
GROUP BY father;
然后我使用了一个连接到我的最后一个子查询。如果父亲的已删除儿子数与总儿子数相同,则应包括:
SELECT a.father
FROM(
SELECT father, COUNT(*) AS numDeletedSons
FROM rel_accounts
WHERE father IN(
SELECT id
FROM accounts
WHERE deleted = 0 AND type = 'Father')
AND son IN(
SELECT id
FROM accounts
WHERE deleted = 1 AND type = 'Son')
GROUP BY father) a
JOIN(
SELECT father, COUNT(*) AS numSons
FROM rel_accounts
GROUP BY father) b ON b.father = a.father AND b.numSons = a.numDeletedSons;
我收到了您的预期结果。您尝试过什么吗?我在描述中添加了…这非常有效!你赚了一个加号,因为这张专辑同时收录了所有父亲的记录,而儿子为空,我没想到。非常感谢。:)谢谢你把答案分成几部分,我学到了很多。你的惊人程度正在突破极限。:)我不知道我的Rel_Accounts表有空值(父活动没有子活动)@Farhang Amary'Ferhęg的查询解决了这个问题。您的查询从原始问题中提取所有记录。非常感谢!:)@很高兴我能帮忙。你从来没有在你的问题中提到过空儿子,所以我不认为这是一个考虑。