使用 EXCEPT SQLite 命令删除除一行以外的所有行

Remove all the rows except one with the EXCEPT SQLite command

从一个数据集character中有一个名字列,我想查询其中的两个名字最短和最长的名字,以及它们各自的长度以及何时有不止一个最小或最大的名字,我选择按字母顺序排在第一位的那个。

通过该查询,我得到了所有最短和最长的名称 (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

我希望保留第一个最短的名字,但它没有出现。

我会在这里使用 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);

当您在 B 查询中设置 OFFSET 2 时,您不会得到:
第一个字母以外的所有最短名字
相反,你得到:
所有最短的名字,除了 前 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 子句(以及 LIMITOFFSET)仅适用于您的 B 查询,但是这不是它的解释方式。
实际上 ORDER BY(以及 LIMITOFFSET)在返回行后应用于 整个查询

要使用类似于您的代码获得您想要的结果,您必须使用子查询来包装您的 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
)