【问题标题】:ORDER BY with a UNION of disparate datasets (T-SQL)ORDER BY 与不同数据集的 UNION (T-SQL)
【发布时间】:2010-11-03 12:11:42
【问题描述】:

我有一个查询,UNION 的两个数据集有些相似,但它们都有一些列在另一个中不存在(即,这些列在结果 UNION 中具有 NULL 值。)

问题是,我需要 ORDER 使用仅存在于一组或另一组中的那些列来生成结果数据,以便以对软件端友好的格式获取数据。

例如:Table1 有字段ID, Cat, PriceTable2 具有字段 ID, Name, AbbrvID 字段在两个表之间是通用的。


我的查询看起来像这样:

SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1 
UNION 
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2 
ORDER BY Price DESC, Abbrv ASC 

ORDER BY 是我卡住的地方。数据如下所示:

100   Balls     1.53                       
200   Bubbles   1.24                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200                     RedWand    201RW   
200                     BlueWand   202BW   

...但我希望它看起来像这样:

100   Balls     1.53                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200   Bubbles   1.24                       
200                     RedWand    201RW   
200                     BlueWand   202BW   

我希望这可以在 T-SQL 中完成。

【问题讨论】:

  • id 没有将您的 T2 产品链接到 T1 产品吗?如果不是,你怎么知道 RedWand 和 BlueWand 是在 Bubbles 之后直接出现的?
  • 他在问题中说:“Table2有字段ID(和Table1一样)”
  • 感谢大家的所有回答;这只是我的第一个问题,但这似乎已经是一个很棒的社区。此外,对于那些批评我的问题所暗示的“架构”的人——请注意我在接受的答案中上面和下面所说的话:这是一个愚蠢的例子!我的问题中的“表”实际上代表了两个非常复杂的 SELECT 查询,它们涉及多个表和子查询,以及聚合和计算字段。再次感谢!

标签: sql sql-server tsql join union


【解决方案1】:
Select ID, Cat, Price, Name, Abbrv
From
(SELECT t1.ID, t1.Cat, t1.Price, t1.Price AS SortPrice, NULL as Name, NULL as Abbrv 
FROM t1
UNION
SELECT t2.ID, NULL as Cat, NULL as Price, t1.Price as SortPrice, t2.Name, t2.Abbrv 
   FROM t2
   inner join t1 on t2.id = t1.id
) t3
ORDER BY SortPrice DESC, Abbrv ASC

不知何故,您必须知道表 2 中的数据链接到表 1 并共享价格。由于 abbrv 中的 Null 会先出现,因此无需创建 SortAbbrv 列。

【讨论】:

  • 运行此查询会产生语法错误,除非子查询有别名。我为你做了更正。 +1
  • 对,所以本质上这只是将价格放入第二个查询中,以便对其进行排序。如果实际查询不是那么复杂,这是一个很好的解决方案——它有子查询和聚合和计算字段,其中一个是主要的排序器(即本例中的价格) .我实际上需要做的是再次为 UNION 下部的 JOIN 复制整个第一个查询。所以 +1 并接受了,但我不会再浪费时间试图让真实的东西像这样工作;在代码中操作数据要容易得多,而且可能更干净。
【解决方案2】:

您应该使用 UNION ALL 而不是 UNION 来节省重复检查的成本。

SELECT *
FROM
(
SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1
UNION ALL
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2
) as sub
ORDER BY
  ID,
  CASE WHEN Price is not null THEN 1 ELSE 2 END,
  Price DESC,
  CASE WHEN Abbrv is not null THEN 1 ELSE 2 END,
  Abbrv ASC

【讨论】:

  • 我正在处理的真正查询确实有 UNION ALL。再一次,ID 不是主要的 ORDER-er,Price 是。 ID 不能用于在我基于此的“真实”查询中进行排序。
【解决方案3】:

一个快速的解决方案是在临时表或表变量中执行 2 次插入操作,作为插入临时表的一部分,您可以设置一个标志列来帮助排序,然后按该标志列排序。

【讨论】:

  • 我确实想过,但试图避免它。不过答案很好。
【解决方案4】:

我想说最坏的情况是您创建一个临时表,其中所有字段都从 T1 和 T2 执行 INSERT INTO 临时表,然后从临时表中按顺序选择。

即。创建一个临时表(例如#temp),其中包含 Id、Cat、Price、Name、Abbrv 字段,然后:

SELECT Id, Cat, Price, null, null INTO #temp FROM T1
SELECT Id, null, null, Name, Abbrv INTO #temp FROM T2
SELECT * FROM #temp ORDER BY Id, Price DESC, Abbrv ASC

注意:我不能 100% 确定插入的 null 语法,但我认为它会起作用。

编辑:在 id 之后按价格和缩写添加排序...如果 Id 没有链接 T1 和 T2,那又是什么?

【讨论】:

  • 忽略ID;价格是主要的订单。
猜你喜欢
  • 2014-09-26
  • 2010-10-04
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
相关资源
最近更新 更多