带有GROUP BY和CASE子句的SQLite查询

crcmnpdw  于 2023-01-21  发布在  SQLite
关注(0)|答案(2)|浏览(144)

在SQLite DB中,我在表items中有以下数据结构(为清晰起见,进行了简化):
| 身份证|存储ID|存档的|
| - ------|- ------|- ------|
| 1个|a-1|无|
| 第二章|a-1|1个|
| 三个|a-1|1个|
| 四个|B -1|无|
| 五个|B -1|无|
| 六个|B -1|无|
| 七|B -1|无|
| 八个|B -1|1个|
我想选择已存档的所有项目(archived = 1),并按storeId对尚未存档的项目进行分组。
为此,我编写了以下查询:

const queryString = `
  SELECT *
  FROM items
  GROUP BY 
    CASE
      WHEN items.archived = 1  
        THEN items.id
      ELSE IFNULL(storeId, id)
    END
`;

我的问题是,具有storeId的非存档项目(其中存在存档项目)从未显示。它们似乎与具有相同storeId值的存档项目分组在一起。
换句话说,使用该查询和该数据,我只得到以下内容:
| 身份证|存储ID|存档的|
| - ------|- ------|- ------|
| 第二章|a-1|1个|
| 三个|a-1|1个|
| 八个|B -1|1个|
我想我错过了一些GROUP BY是如何工作的。我如何才能达到我预期的结果?

xiozqbni

xiozqbni1#

对任何感兴趣的人来说,答案是按多列分组,并进行连接:

const queryString = `
  SELECT items.*, items.storeId || ' ' || items.archived AS concatenatedValues
  FROM items
  GROUP BY 
    CASE
      WHEN items.archived = 1 THEN items.id
      ELSE concatenatedValues
    END
`;
np8igboo

np8igboo2#

如果您需要的是storeIdarchived = 0的最小值id所在的行,则可以使用CASE表达式中的MIN()窗口函数来完成此操作:

SELECT DISTINCT 
       CASE 
         WHEN archived THEN id
         ELSE MIN(id) OVER (PARTITION BY storeId)
       END AS id,
       storeId,
       archived
FROM items;

或者,如果archived = 0(如果存在)不总是每个storeId中的第一个,则使用FIRST_VALUE()窗口函数:

SELECT DISTINCT 
       CASE 
         WHEN archived THEN id
         ELSE FIRST_VALUE(id) OVER (PARTITION BY storeId, archived ORDER BY id)
       END AS id,
       storeId,
       archived
FROM items;

请参见demo

相关问题