最后按 Sequelize 顺序对 null 和空字符串进行排序

Sorting Nulls and Empty Strings at Last in Sequelize Order By

提问人:Waqar Ali 提问时间:12/8/2022 最后编辑:Waqar Ali 更新时间:12/13/2022 访问量:995

问:

我想按续集顺序对最后的 Nulls 和 Empty stings 进行排序。

这是我能够运行的查询:

data = await Provider.findAll({
            where: {
              search
            },
            order: [
              ['lastName', 'ASC NULLS LAST']
            ]
          });

默认情况下,Postgress 最后对 Null 值进行排序,但对于空字符串,它不会将其视为 NULL,而是将其视为长度为 0 的字符串。 我想最后用空字符串对值进行排序,无论空字符串是在名字还是姓氏,都应该在列表末尾排序,优先考虑同时具有两个名字的名称。 我正在使用 postgress 和 sequelize。

更新: 以下是我得到的结果:

姓氏 名字
l_name1 f_name1
l_name2 empty_str
l_name3 f_name3
l_name4 f_name4
l_name5 f_name5

以下是预期结果:

姓氏 名字
l_name1 f_name1
l_name3 f_name3
l_name4 f_name4
l_name5 f_name5
l_name2 empty_str

对于 lastName 为空,但 firstName 不为空(预期结果):

姓氏 名字
l_name1 f_name1
l_name4 f_name4
l_name5 f_name5
l_name2 empty_str
empty_str f_name3
PostgreSQL 续集.js SQL-排序

评论


答:

0赞 Dawood Fayyaz 12/8/2022 #1

你可以这样把多个条件按顺序排列

order: [
    ['lastName', 'ASC NULLS LAST'],
    [sequelize.literal('CASE WHEN lastName = '' THEN 0 ELSE 1 END'), 'DESC']
],

让我知道这是否有效

评论

0赞 Waqar Ali 12/9/2022
对我不起作用,但 NULLIIF 工作正常。
0赞 Emma 12/9/2022 #2

另一种选择。

如果要最后对 null 或空字符串进行排序,而不对 null 或空字符串进行排序,则可以使用 .NULLIF

order: [
    [sequelize.fn('NULLIF', sequelize.col('lastName'), ''), 'NULLS LAST']
]

更新

添加 firstName 排序。

order: [
    [sequelize.fn('NULLIF', sequelize.col('lastName'), ''), 'NULLS LAST'],
    [sequelize.fn('NULLIF', sequelize.col('firstName'), ''), 'NULLS LAST']
]

这将导致这样的顺序。

姓氏 名字
史密斯 爱丽丝
史密斯 鲍勃
史密斯
史密斯
爱丽丝
爱丽丝

更新2

按以下标准排序。

  • lastName 和 firstName 都不为 null,也不为空
  • lastName 或 firstName 不为 null 或不为空
  • lastName 和 firstName 均为 null 或空
order: [
    [sequelize.literal(`
         CASE 
             WHEN NULLIF("lastName", '') IS NULL AND NULLIF("firstName", '') IS NULL THEN 2
             WHEN NULLIF("lastName", '') IS NULL OR NULLIF("firstName", '') IS NULL THEN 1
             ELSE 0
         END
    `)]
]

评论

0赞 Waqar Ali 12/9/2022
它有效,感谢您的回答,这是否也是一种将其应用于“first_name”的方法?这意味着添加一个 AND 条件,检查名字或姓氏中是否有空字符串。
0赞 Emma 12/9/2022
很酷,只是为了清楚起见,您能否添加一些示例(non null、lastname null、firstname null、both null)来展示它应该如何排序?如果某个顺序无关紧要,请添加注释(例如:firstname null 和 lastname null 可以按任一顺序)?
0赞 Waqar Ali 12/12/2022
基本上,我想将 Null 或 Empty String 值放在列表的末尾,无论“last”还是“first”名称中有 Null 或空字符串。以下是 4 种情况: 1-两者都不为空:列表应按姓氏字母顺序排序。2-Both Null:列表应按姓氏字母顺序排列,但空字符串应位于列表末尾。3-姓氏 null:与 2 相同。4-名字 Null:列表应按姓氏字母顺序排列,但名字中的空字符串应位于列表末尾。即使姓氏有价值。Nullif 涵盖前 3 种情况。
0赞 Emma 12/12/2022
我更新了答案。请检查订购是否符合您的要求。
0赞 Waqar Ali 12/13/2022
感谢您的更新,不幸的是,“名字”大小写没有给出所需的结果。当名字为空时,顺序根据姓氏。其他 3 种情况工作正常。我在想,如果有一个 AND 条件我们可以做,即 NULLIF(last_name, '') 和 NULLIF(first_name, '')。这可能会解决它。
0赞 Waqar Ali 12/13/2022 #3

在艾玛的回答的帮助下,我能够为我的问题获得所需的结果。 基本上,我希望在“姓氏”的基础上进行排序,并在搜索列表的末尾显示缺少“last_name”或“first_name”的人,优先考虑同时具有名字和姓氏的人。

我能够通过在文字中添加 Case 语句来获得所需的结果。对于那些不了解“sequelize.literal”的人来说,它用于在使用 sequelize 时编写原始 SQL 查询。

'sequelize.literal'的作用是检查名字或姓氏是否等于空字符串,然后使该行为 NULL。然后在“last_name”上进行排序,将所有 Null 值放在列表的末尾。

data = await Provider.findAll({
            where: {
              search
            },
            order: [
              [sequelize.literal(`CASE WHEN last_name = '' OR first_name = '' THEN NULL ELSE 0 END`), 'ASC'],
              ['lastName', 'ASC NULLS LAST']
            ],
          });