2009-06-16 66 views
13

我有一个查询,UNIONs两个有点类似的数据集,但他们都有一些列不存在于另一个 - 即列在结果UNION中有NULL值。 UNION的目的是以软件方面的友好格式获取数据。TSQL ORDER-BY与一个不同的数据集联盟

问题是,我需要使用那些只存在于一个或另一个集合中的列对结果数据进行排序。

例如:表1具有字段ID,Cat,Price。表2具有字段ID(与表1中相同),名称,缩写。

我的查询看起来是这样的:

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--

(道歉,如果这些都很难读 - didn't知道该怎么显示表)

请记住,这是一个非常愚蠢的例子和谚语“使用JOIN!”答案是不适用的(即我已经知道如何加入他们,但这不是我想要的最终结果)。

这很可能是实现这一目标的唯一途径是通过软件处理数据,一旦它来自数据层背 - 如果是这样的话,那么就这样吧。但我希望可以在TSQL中完成。

+0

请不要将您的T2产品链接到T1产品? 如果没有,你怎么知道RedWand&BlueWand在Bubbles之后直接出现? – mundeep 2009-06-17 01:14:20

+0

他在问题中说:“表2有字段ID(与表1相同)” – 2009-06-17 03:11:34

+0

感谢所有人的答案;这只是我的第一个问题,但这已经看起来像一个伟大的社区。另外,对于那些会批评我的问题所暗示的“架构”的人,请注意我在上面和下面所接受的答案中所说的话:这是一个愚蠢的例子!我的问题中的'表'实际上代表了两个非常复杂的SELECT查询,涉及多个表和子查询,包含聚合和计算字段。再次感谢! – NateJ 2009-06-17 16:02:06

回答

22
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中的空值将首先出现,因此不需要创建SortAbbrv列。

1

一个快速的解决办法是做2插入到一个临时表或表变量和插件的一部分到临时表中,可以设置标志列,以帮助由标志列排序,然后顺序。

+0

我的确想到了这一点,但试图避免它。虽然答案很好。 – NateJ 2009-06-16 23:30:05

0

关闭我的头顶我会说最糟糕的情况是你创建一个临时表,所有的字段都从T1 & T2执行一个INSERT IN临时表,然后从临时表中选择一个order by。

即。同场标识,猫,价钱,名称,Abbrv创建临时表(如#TEMP),然后输入:

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%认为它会起作用。

编辑:增加订购价格& Abbrv后id ...如果Id不链接T1 & T2那么是什么?

+0

忽略ID;价格是主要订购者。 – NateJ 2009-06-16 23:28:49

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