外部 SELECT 获取嵌套 SELECT 的第一个结果
Outer SELECT takes the first result of the nested SELECT
我正在尝试获取课程中员工的最后一个操作(状态)为“已注册”的课程
这是所有课程中的table
CREATE TABLE course (
id integer primary key,
name text
);
这是所有员工的table,
nid = 国民身份证
CREATE TABLE employee (
id integer primary key,
nid integer,
name text
);
这是一个table,我在其中记录所有课程的员工的所有行为
CREATE TABLE tran (
id integer primary key,
nid integer,
cid integer,
state text
);
这是我的数据
INSERT INTO course VALUES (1, "c1"); --> required result
INSERT INTO course VALUES (2, "c2");
INSERT INTO course VALUES (3, "c3"); --> required result
INSERT INTO employee VALUES (1, 111, "e1");
INSERT INTO employee VALUES (2, 222, "e2");
INSERT INTO employee VALUES (3, 333, "e3");
INSERT INTO tran VALUES (1, 111, 1, "enrolled"); --> latest action
INSERT INTO tran VALUES (3, 222, 3, "enrolled");
INSERT INTO tran VALUES (4, 222, 3, "rejected");
INSERT INTO tran VALUES (5, 111, 2, "enrolled");
INSERT INTO tran VALUES (6, 111, 2, "withdrawn");
INSERT INTO tran VALUES (7, 111, 3, "enrolled"); --> latest action
我应该得到上面标记的行
我可以使用这个获取每门课程的最新操作
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled";
Output:
1
3
但是当我尝试用另一个 SELECT 语句将其包装起来以获取课程名称时,我只得到第一个
SELECT id, name FROM course AS c
WHERE c.id = (
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled"
);
Output:
1|c1
乍一看,您可能会尝试使用 IN
运算符。
SELECT id, name FROM course AS c
WHERE c.id IN (
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled"
);
不过我自己还没有测试过。
一种方法使用聚合:
select t.nid, t.cid
from tran t
group by t.nid, t.cid
having max(t.id) = max(case when t.state = 'enrolled' then id end);
此 returns employee/course 组合,其中 tran
中的最后一个 ID 是 'enrolled'
。
如果您需要更多信息,可以在其他表格中join
。
我正在尝试获取课程中员工的最后一个操作(状态)为“已注册”的课程
这是所有课程中的table
CREATE TABLE course (
id integer primary key,
name text
);
这是所有员工的table, nid = 国民身份证
CREATE TABLE employee (
id integer primary key,
nid integer,
name text
);
这是一个table,我在其中记录所有课程的员工的所有行为
CREATE TABLE tran (
id integer primary key,
nid integer,
cid integer,
state text
);
这是我的数据
INSERT INTO course VALUES (1, "c1"); --> required result
INSERT INTO course VALUES (2, "c2");
INSERT INTO course VALUES (3, "c3"); --> required result
INSERT INTO employee VALUES (1, 111, "e1");
INSERT INTO employee VALUES (2, 222, "e2");
INSERT INTO employee VALUES (3, 333, "e3");
INSERT INTO tran VALUES (1, 111, 1, "enrolled"); --> latest action
INSERT INTO tran VALUES (3, 222, 3, "enrolled");
INSERT INTO tran VALUES (4, 222, 3, "rejected");
INSERT INTO tran VALUES (5, 111, 2, "enrolled");
INSERT INTO tran VALUES (6, 111, 2, "withdrawn");
INSERT INTO tran VALUES (7, 111, 3, "enrolled"); --> latest action
我应该得到上面标记的行
我可以使用这个获取每门课程的最新操作
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled";
Output:
1
3
但是当我尝试用另一个 SELECT 语句将其包装起来以获取课程名称时,我只得到第一个
SELECT id, name FROM course AS c
WHERE c.id = (
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled"
);
Output:
1|c1
乍一看,您可能会尝试使用 IN
运算符。
SELECT id, name FROM course AS c
WHERE c.id IN (
SELECT cid FROM tran AS t1
WHERE t1.id = (
SELECT MAX(t2.id) FROM tran AS t2
WHERE t1.nid = 111
AND t1.cid = t2.cid
)
AND t1.state = "enrolled"
);
不过我自己还没有测试过。
一种方法使用聚合:
select t.nid, t.cid
from tran t
group by t.nid, t.cid
having max(t.id) = max(case when t.state = 'enrolled' then id end);
此 returns employee/course 组合,其中 tran
中的最后一个 ID 是 'enrolled'
。
如果您需要更多信息,可以在其他表格中join
。