【问题标题】:Remove all the rows except one with the EXCEPT SQLite command使用 EXCEPT SQLite 命令删除除一行之外的所有行
【发布时间】:2020-01-05 03:18:17
【问题描述】:

从具有名称列的数据集 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

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

【问题讨论】:

    标签: sqlite except


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      当您在 B 查询中设置 OFFSET 2 时,您不会得到:
      除了 前 1 按字母顺序排列的所有最短名称
      相反,您会得到:
      除了前 2 个按字母顺序排列的所有最短名称
      因为这是 OFFSET 2 所做的:它跳过前 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
      )
      

      【讨论】:

        猜你喜欢
        • 2020-04-14
        • 1970-01-01
        • 2010-09-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多