我正在尝试使用postgresql进行查询.该数据库包含两个关系:"王国",其中包括一些英国国王,以及"dinasty",其中包含一些来自斯图亚特恐怖的人
关系"王国"包括国王的名字,当他的王国开始和结束时."dinasty"的关系包括姓名,性别,出生和死亡.
我想要查询的是他去世时最年长的国王.
根据我的查询,我在LINE 3(NOT IN)收到此错误: subquery has too many columns
这是查询:
SELECT kingdom.king, dinasty.birth, dinasty.death
FROM kingdom, dinasty
WHERE kingdom.king = dinasty.name AND kingdom.king NOT IN
(
SELECT DISTINCT R1.king, R1.birth, R1.death
FROM
(
SELECT DISTINCT R1.king, D1.birth, D1.death
FROM kingdom AS R1, dinasty AS D1, dinasty AS D2
WHERE R1.king=D1.name
) AS R1,
(
SELECT DISTINCT R1.king, D1.birth, D1.death
FROM kingdom AS R1, dinasty AS D1, dinasty AS D2
WHERE R1.king=D1.name
) AS R2
WHERE R1.death-R1.birth < R2.death-R2.birth
);
Run Code Online (Sandbox Code Playgroud)
NOT IN内部的内容是正确的.
Joã*_*lva 25
您在子查询中预测了三列,但在子句中比较了它们中的一个IN.在子查询中只选择所需的列(r1.king)IN:
SELECT kingdom.king, dinasty.birth, dinasty.death
FROM kingdom, dinasty
WHERE kingdom.king = dinasty.name AND kingdom.king NOT IN
(
SELECT DISTINCT R1.king
FROM
(
SELECT DISTINCT R1.king, D1.birth, D1.death
FROM kingdom AS R1, dinasty AS D1, dinasty AS D2
WHERE R1.king=D1.name
) AS R1,
(
SELECT DISTINCT R1.king, D1.birth, D1.death
FROM kingdom AS R1, dinasty AS D1, dinasty AS D2
WHERE R1.king=D1.name
) AS R2
WHERE R1.death-R1.birth < R2.death-R2.birth
);
Run Code Online (Sandbox Code Playgroud)
Jim*_*sby 10
正如所回答的,您的列数不匹配,但有一种更简单的方法来编写它.
在编写查询时,最好分阶段进行思考.首先,你需要知道每个国王去世时的年龄:
SELECT *, death-birth AS lived_for FROM dinasty
Run Code Online (Sandbox Code Playgroud)
现在你已经拥有了它,你可以使用DISTINCT ON找到每个王国最长寿的国王
SELECT DISTINCT ON( name ) name, birth, death, lived_for
FROM (
SELECT *, death-birth AS lived_for FROM dinasty
) a
ORDER BY name, lived_for DESC
;
Run Code Online (Sandbox Code Playgroud)
distinct on将取每个不同值的第一行,因此将它与正确值配对非常重要ORDER BY.首先,我们以dinasty的名义命令,然后国王按降序排列多长时间.这意味着每个晚宴上显示的第一个国王将是最长寿的,这是DISTINCT ON将为每个晚宴保留的记录.
请注意,我还将JOIN删除为kindgom,但如果需要,您可以将其添加回来:
SELECT k.*, oldest.*
FROM (
SELECT DISTINCT ON( name ) name, birth, death, lived_for
FROM (
SELECT *, death-birth AS lived_for FROM dinasty
) a
ORDER BY name, lived_for DESC
) oldest
JOIN kingdom k ON k.king = oldest.name
;
Run Code Online (Sandbox Code Playgroud)
最后,如果您需要在子选择中使用多个列,则可以使用ROW()构造:
SELECT ...
FROM table_a
WHERE ROW(f1, f2, f3) NOT IN (SELECT f1a, f2a, f3a FROM ... )
;
Run Code Online (Sandbox Code Playgroud)