表A具有值
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
表B具有值
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 1 | 1 | started |
| 2 | 2 | stopped |
| 3 | 1 | stopped |
| 4 | 1 | stopped |
+----+-----------+----------+
关系B为1:N
如何仅从状态为未启动的表A中获取这些ID。
SELECT
id
FROM A
JOIN B ON A.id=B.parent_id and B.status <> 'started';
当我运行上面的查询时,我得到这个结果
+----+
| id |
+----+
| 1 |
| 2 |
+----+
不是只显示值2,而是也显示1。我写的查询有什么问题?
答案 0 :(得分:1)
显示未启动状态。
SELECT A.id FROM A JOIN B ON A.id=B.parent_id and B.status != 'started'
输出:
+----+
| id |
+----+
| 2 |
| 1 |
| 1 |
+----+
答案 1 :(得分:0)
在您的查询中,parent_id 2返回,因为它也停止了 您可以尝试对所述
使用not in子查询SELECT id
FROM A
JOIN B ON A.id=B.parent_id
WHERE B.parent_id NOT IN (
select parent_id
from B
B.status = 'started'
)
答案 2 :(得分:0)
我会使用/*
* calls:
*
* File {Close, Read, Write, Size, Sync}
* {Path Name Open, Allocate, Free} File
*
* These are NOT JUST RENAMINGS OF THE UNIX ROUTINES.
* Use them for all file activity...
*
* File fd;
* fd = PathNameOpenFile("foo", O_RDONLY);
*
* AllocateFile();
* FreeFile();
*
* Use AllocateFile, not fopen, if you need a stdio file (FILE*); then
* use FreeFile, not fclose, to close it. AVOID using stdio for files
* that you intend to hold open for any length of time, since there is
* no way for them to share kernel file descriptors with other files.
*
* Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate
* open directories (DIR*), and OpenTransientFile/CloseTransientFile for an
* unbuffered file descriptor.
*
* If you really can't use any of the above, at least call AcquireExternalFD
* or ReserveExternalFD to report any file descriptors that are held for any
* length of time. Failure to do so risks unnecessary EMFILE errors.
*/
:
not exists
这将从select a.id
from a
where not exists (select 1 from b where b.parent_id = a.id and b.status = 'started')
中筛选出行,其中a
中的任何子记录的状态已开始。
答案 3 :(得分:0)
查询的“未开始”部分将表B过滤到以下内容:
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 2 | 2 | stopped |
| 3 | 1 | stopped |
| 4 | 1 | stopped |
+----+-----------+----------+
然后,您的联接正在查找表A中的ID与表B的父ID匹配的行-它将正确返回(但不会两次计数1)
如果您希望上半年返回:
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 2 | 2 | stopped |
+----+-----------+----------+
PLUS the rows from table A not referred to in table B....
那么上述GMB的答案是正确的-
select a.id
from a
where not exists (select 1 from b where b.parent_id = a.id and b.status = 'started')
这是一个小提琴。 https://sqltest.net/#1005425
但是,按照建议,您可能会在表B中产生许多不必要的重复-许多行说开始和停止,不一定按时间顺序排列(例如-A.id = 1的第一条记录建议这样做)启动后,第3条和第4条记录(大概在此后输入)将其停止,但是您将排除此记录以被启动。
为什么不更改表结构以更新一行?