简体   繁体   English

如何通过链接表按空值排序

[英]How to order by nulls-last by a linked table

I have two tables Person and PersonSkill我有两张表PersonPersonSkill

Person

+----+----------+
| ID | NAME     |
+----+----------+
| 1  | Person 1 |
| 2  | Person 2 |
| 3  | Person 3 |
+----+----------+

PersonSkill个人技能

+-----------+---------+------+
| PERSON_ID | SKILL   | SORT |
+-----------+---------+------+
| 1         | Sing    | 20   |
| 1         | Playful | 10   |
| 2         | Sing    | 10   |
| 1         | Bowl    | 30   |
| 1         | SQL     | 40   |
+-----------+---------+------+

I'm trying to write a order by which will sort the persons by skills alphabetically but nulls last.我正在尝试编写一个顺序,该顺序将按字母顺序按技能对人员进行排序,但最后为空值。

Looking for something like this:寻找这样的东西:

SELECT distinct
  p.*,
  STUFF(
    (SELECT ',' + ps.SKILL
      FROM PersonSkill ps
      WHERE ps.PERSON_ID = p.ID
      ORDER BY ps.SORT
      FOR XML PATH('')
    ), 1, 1, '') sortRule
FROM Person p
ORDER BY IIF(sortRule is null, 1, 0) asc, sortRule asc

But for some reason I can't use sortRule inside an IIF or a case operation within ORDER BY as it's giving me this error: Invalid column name 'sortRule'.但是由于某种原因,我不能在IIF使用 sortRule 或在 ORDER BY 中使用case操作,因为它给了我这个错误: Invalid column name 'sortRule'.

If I remove the STUFF sortRule from the select statement it will tell me that it is required to be there when using alongside distinct .如果我从 select 语句中删除STUFF sortRule ,它会告诉我它在与distinct一起使用时需要在那里。 I also can't just copy the STUFF down to the order by as it will say: ORDER BY items must appear in the select list if SELECT DISTINCT is specified.我也不能只是将STUFF复制到 order by 中,因为它会说: ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

As you're performing string aggregation, then you should be using a GROUP BY , not DISTINCT .当您执行字符串聚合时,您应该使用GROUP BY ,而不是DISTINCT As for sorting on sortRule , you can't wrap a column's alias in an expression in the ORDER BY .至于排序sortRule ,您不能将列的别名包装在ORDER BY的表达式中。 One method, therefore, is to use a CTE:因此,一种方法是使用 CTE:

WITH CTE AS(
    SELECT p.Id,
           p.[Name],
           STUFF((SELECT ',' + ps.SKILL
                  FROM dbo.PersonSkill ps
                  WHERE ps.PERSON_ID = p.ID
                  ORDER BY ps.SORT
                  FOR XML PATH(''),TYPE).value('(./text())[1]','varchar(MAX)'),1,1,'') AS sortRule
    FROM dbo.Person p
    GROUP BY p.Id,
             p.[Name])
SELECT *
FROM CTE
ORDER BY CASE WHEN sortRule IS NULL THEN 1 ELSE 0 END,
         sortRule;

db<>fiddle 数据库<>小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM