从具有名称列的数据集字符中,我要查询两个名称中最短和最长的名称,以及它们各自的长度以及最小或多于一个的名称。最大的名字,我选择按字母顺序排列的第一个。
通过该查询,我得到了所有最短和最长的名称( A )
SELECT
name, LENGTH(name) AS LEN
FROM
character
WHERE
length(name) = (SELECT MAX(LENGTH(name)) FROM character)
OR length(name) = (SELECT MIN(LENGTH(name)) FROM character)
有了这个,除了第一个按字母顺序排列的名字( B )
,我得到了所有最短的名字SELECT
name, LENGTH(name) AS LEN
FROM
character
WHERE
length(name) = (SELECT MIN(LENGTH(name)) FROM character)
ORDER BY
name DESC
LIMIT 10 OFFSET 2;
当我尝试从 A
中删除 B 时A EXCEPT B
我希望保留最短的名字,但不会出现。
答案 0 :(得分:1)
我会在这里使用ROW_NUMBER
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY LENGTH(name), name) rn_min,
ROW_NUMBER() OVER (ORDER BY LENGTH(name) DESC, name) rn_max
FROM character
)
SELECT name, LENGTH(name) AS LEN
FROM cte
WHERE 1 IN (rn_min, rn_max)
ORDER BY LENGTH(name);
答案 1 :(得分:0)
在 B 查询中设置OFFSET 2
时,不会得到:
除按字母顺序排列的前1 以外的所有最短名称
相反,您得到:
除按字母顺序排列的前2 以外的所有最短名称,
因为这就是OFFSET 2
的作用:跳过前两行。
代码的另一个问题是 B 查询中的ORDER BY
子句。
如果您有这样的话:
SELECT name,LENGTH(name) AS LEN FROM character
WHERE length(name) = (select max( LENGTH(name)) from character )
or length(name) = (select min( LENGTH(name)) from character)
EXCEPT
SELECT name,LENGTH(name) AS LEN FROM character
WHERE length(name) = (select min( LENGTH(name)) from character)
ORDER BY name desc LIMIT 10 OFFSET 2;
您可能会认为ORDER BY
子句(以及LIMIT
和OFFSET
)仅适用于您的 B 查询,但是事实并非如此。解释。
实际上,在返回行之后,将ORDER BY
(以及LIMIT
和OFFSET
)应用于整个查询。
要使用与您的代码相似的代码来获得所需的结果,您必须使用子查询来包装您的 B 查询,如下所示:
SELECT name,LENGTH(name) AS LEN FROM character
WHERE length(name) = (select max( LENGTH(name)) from character )
or length(name) = (select min( LENGTH(name)) from character)
EXCEPT
SELECT * FROM (
SELECT name,LENGTH(name) AS LEN FROM character
WHERE length(name) = (select min( LENGTH(name)) from character)
ORDER BY name desc LIMIT 10 OFFSET 1
)