SQL:ORDER BY 两列混合,不基于优先级

Posted

技术标签:

【中文标题】SQL:ORDER BY 两列混合,不基于优先级【英文标题】:SQL: ORDER BY two columns intermixed, not priority based 【发布时间】:2010-12-22 19:08:21 【问题描述】:

我正在使用 mysql。我必须按姓氏排序联系人的姓名,但如果没有姓氏,我会按名字排序。

这看起来像:

ORDER BY lastname = "", lastname, firstname

但是,这会使姓氏显示在顶部。我想要的行为是将名字和姓氏混合在一起,就像它们来自同一个字段一样。

示例(假设这些是名称):

A,T 
Z,G 
A 
B 
C

对比:

A
A,T
B
C
Z,G

谢谢

【问题讨论】:

姓氏值是空值还是零长度字符串? 【参考方案1】:

使用COALESCE 和NULLIF:

ORDER BY COALESCE(NULLIF(LastName, ''), FirstName), FirstName

【讨论】:

就是这个!!很好地适应了第一个解决方案,因此它适用于空字段。 +1 很好的解决方案...我什至没有想到...但我仍然不同意空字符串值。 @John Hartsock - 这取决于商店中的数据库设计和约定。我同意,一般来说,我希望像 Pele 这样的人(已知为空白)的 LastName 和 Office Space 的 Bob 的 NULL LastName(未知,但假设可能存在)。但是,在这种情况下,我想所需的排序行为没有区别。【参考方案2】:

尝试使用Coalesce注意:这要求您不要使用空字符串(即“”)来存储空姓氏

ORDER BY Coalesce(LastName, FirstName)

按照评论中的建议,再次将 FirstName 添加到 order By 列表中,您将正确地订购两个姓氏相同的人。这是一个例子。

ORDER BY Coalesce(LastName, FirstName), FirstName

【讨论】:

...然后再次添加 Firstname,这样两个姓氏相同的联系人将被正确排序。 我刚刚尝试过,现在联系人的顺序似乎几乎是随机的。在 Coalesce 之前它肯定更有条理...... 我按照 Axel 的建议进行了尝试,它看起来与 ORDER BY lastname, firstname 相同。如果这很重要,我将在查询中加入几个表。 @Tyler 我刚刚在一个示例表上运行它,它按预期工作?所以我对你之前的陈述感到很困惑。 @Tyler 对于这一列有一种简单的方法。 Update yourtable set lastname = null where lastname = '' 请注意,将数据输入数据库的任何内容也需要更新。【参考方案3】:

ORDER BY 支持自定义排序。但考虑到您的逻辑,我建议您在 SELECT 中使用 CONCAT 创建一个字段,然后对其进行排序。

SELECT *, IF(LENGTH(lastname) = 0, firstname, CONCAT(lastname, ', ', firstname)) AS fullname
FROM contacts
ORDER BY fullname;

这还具有在基于相同排序逻辑的结果中返回 fullname 的好处。

【讨论】:

+1 虽然我不同意在姓氏列中使用空字符串。我同意您的解决方案适用于 OP 的问题【参考方案4】:
ORDER BY
CASE  
  WHEN LName is null
  THEN FName 
  ELSE LName
  END 

更多here

【讨论】:

这没有给出预期的结果。可能是因为我用 "" 代替了 null。

以上是关于SQL:ORDER BY 两列混合,不基于优先级的主要内容,如果未能解决你的问题,请参考以下文章

SQL ORDER BY 两个具有优先级的字段,而不是一个接一个

SQL,Order By - 如何赋予其他列更多权限?

SQL基础-order by

若sql语句中order by指定了多个字段,则怎么排序?

若sql语句中order by指定了多个字段,则怎么排序?

详解基于MSSQL “order by”语句报错的SQL注入技术