sql server 查询 order by 与 union 并替换多个列的空值

Posted

技术标签:

【中文标题】sql server 查询 order by 与 union 并替换多个列的空值【英文标题】:sql server query order by with union and replacing multiple columns' null value 【发布时间】:2012-09-28 09:21:41 【问题描述】:

我有一个查询要从 4 个不同的表中获取记录。我正在使用union 来获取最终记录。我的问题是我在所有 4 个表中没有相同数量和类型的列,所以我正在制作具有 null 值的虚拟列。我面临的问题是排序。我正在使用 datetime desc 对记录进行排序,但有时当日期相同时,我希望警报上的二级排序列可以是 High、Medium 或 Null 类型。我想要 Null 列在底部,但我在顶部。所以我尝试在ORDER BY 子句中使用ISNULL(column_name, 'aaaa'),但我没有得到实际结果。任何人都可以帮忙吗?

SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblA
union  
SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblB
union  
SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblC
union
SELECT CreatedDt as 'Date/Time' , Alert_Type FROM TblD
ORDER BY CreatedDt, ISNULL (Alert_Type,'aa') DESC

错误是

ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.

谢谢你..

【问题讨论】:

你能分享一下查询吗? @Vikdor 和 NG - 我已经发布了 嗯。您需要 SQL Server 和 Oracle 的解决方案吗? (plsql 是 Oracle 的 SQL 方言) 【参考方案1】:

试试这个:

select * from (

SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblA
union  
SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblB
union  
SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblC
union
SELECT CreatedDt as 'Date/Time' , Alert_Type FROM TblD)a
order by CreatedDt desc, 
         case when Alert_Type is null then 0 else 1 end

【讨论】:

谢谢。但是 TblA、TblB 和 TblC 中不存在 Alert_Type 列,因此对于联合子句,我在选择查询中创建了具有空值的虚拟列 [Alert_Type]。您的解决方案给了我同样的错误“如果语句包含 UNION、INTERSECT 或 EXCEPT 运算符,则选择列表中必须出现无效的列名 'Alert_Type'.ORDER BY 项。” @DevendraGohil:这不可能发生,您是否复制了我的完整查询并执行了它。查看此链接以获取示例sqlfiddle.com/#!2/d41d8/2410 @DevendraGohil - 请发布您修改后的查询。这种方法应该可以正常工作。我认为您可能在最终实现它时遗漏了一些东西。 @MartinSmith 在order by 中,union 查询之后似乎不允许表达式引用列。我无法在文档中确认这一点。 @NikolaMarkovinović - 如果联合在派生表中(如此处)并且按外部排序,则很好。【参考方案2】:

如果Alert_TypeTblD 中不能为NULL,您可以这样做:

SELECT CreatedDt as 'Date/Time' , 'aa' AS [Alert_Type] FROM TblA
union  
SELECT CreatedDt as 'Date/Time' , 'aa' AS [Alert_Type] FROM TblB
union  
SELECT CreatedDt as 'Date/Time' , 'aa' AS [Alert_Type] FROM TblC
union
SELECT CreatedDt as 'Date/Time' , Alert_Type FROM TblD
ORDER BY CreatedDt DESC, Alert_Type DESC

注意CreatedDt 之后的DESC(因为你说你想按日期时间列降序排序)。

【讨论】:

我试过了,但在这种情况下它不起作用,因为它没有优先按 CreatedDt 按 desc 顺序排序。我想主要按 CreatedDt 排序,如果多个记录的 CreatedDt 相同,而不是仅按 Alert_Type desc 排序 @DevendraGohil 此查询生成的行的顺序与您的相同。如果要对 CreatedDt 进行降序排序,请在 ORDER BY CreatedDt 之后插入 desc @DevendraGohil:我更新了我的答案,以展示如何为主要排序标准指定降序。 (在您的帖子中错过了那一点,抱歉。)【参考方案3】:

您仍然可以在 ORDER BY 子句中使用 CASE

ORDER BY  CASE WHEN column_name IS NULL
               THEN 1
               ELSE 0
          END ASC --, other sorts
                  -- in these case NULL columns should be on the bottom part

【讨论】:

谢谢,我试过 SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblA union SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblB union SELECT CreatedDt as 'Date/Time' , null AS [Alert_Type] FROM TblC union SELECT CreatedDt as 'Date/Time' , Alert_Type FROM TblD ORDER BY CreatedDt, column_name IS NULL THEN 1 END DESC 但出现错误“ORDER BY 项目必须出现在选择中列出语句是否包含 UNION、INTERSECT 或 EXCEPT 运算符。"

以上是关于sql server 查询 order by 与 union 并替换多个列的空值的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server查询错误-ORDER BY子句在视图中无效

SQL Server 查询错误 -ORDER BY 子句在视图中无效

在SQL Server的子查询视图内联函数等数据库对象中,不应该单独使用ORDER BY语句

JPA 和 SQL Server 的 ORDER BY 子句中的列无效

使用带有 ORDER BY 的 SQL Server 查找累积总和

sql语句在查询分析器中能执行,但是程序却不能执行,一直报错order by 附近有语法错误