我如何将2个select语句组合成一个?

当谈到SQL语法时,我是一个noob。

我有一个有很多行和列的表格:P让我们说看起来像这样:

AAA BBB CCC DDD ----------------------- Row1 | 1 ADX Row2 | 2 BCX Row3 | 3 CDZ 

现在我想创build一个高级select语句,它给了我这个组合(在这里伪SQLish):

 select 'Test1', * from TABLE Where CCC='D' AND DDD='X' select 'Test2', * from TABLE Where CCC<>'D' AND DDD='X' 

输出将是:

 Test1, 1, A, D, X Test2, 2, B, C, X 

我将如何将这两个select语句组合成一个很好的select语句?

如果我像下面那样复杂SQL(因为我自己的SQL语句包含一个exists语句),它会起作用吗? 我只想知道如何组合select,然后尝试将其应用于我的更高级的SQL。

 select 'Test1', * from TABLE Where CCC='D' AND DDD='X' AND exists(select ...) select 'Test2', * from TABLE Where CCC<>'D' AND DDD='X' AND exists(select ...) 

我的REAL SQL语句是这样的:

 select Status, * from WorkItems t1 where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' 

这给了我一个结果。 但是我想把它和这个SELECT语句的一个副本结合起来,并且'状态'字段将被改变为'DELETED'string。

 select 'DELETED', * from WorkItems t1 where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' AND NOT (BoolField05=1) 

你有两个select。 首先是有两个结果集,它们将根据WHERE子句中的条件设置“Test1”或“Test2”,然后将它们联合在一起:

 select 'Test1', * from TABLE Where CCC='D' AND DDD='X' AND exists(select ...) UNION select 'Test2', * from TABLE Where CCC<>'D' AND DDD='X' AND exists(select ...) 

这可能是一个问题,因为你将有效地扫描/查找表两次。

另一种解决scheme是从表中select一次,并根据TABLE中的条件设置“Test1”或“Test2”

 select case when CCC='D' AND DDD='X' AND exists(select ...) then 'Test1' when CCC<>'D' AND DDD='X' AND exists(select ...) then 'Test2' end, * from TABLE Where (CCC='D' AND DDD='X' AND exists(select ...)) or (CCC<>'D' AND DDD='X' AND exists(select ...)) 

这里的问题是你将不得不复制CASE语句和WHERE语句中的过滤条件。

如果他们来自同一张桌子,我认为UNION是你要找的命令。

(如果你需要从不同表格的列中select值,你应该看看JOIN而不是…)

感谢您的input。 试了一下这里提到的东西,这两个是我上class的:

 ( select 'OK', * from WorkItems t1 where exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' AND (BoolField05=1) ) UNION ( select 'DEL', * from WorkItems t1 where exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' AND NOT (BoolField05=1) ) 

 select case when (BoolField05=1) then 'OK' else 'DEL' end, * from WorkItems t1 Where exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' 

这将是最有效的(编辑:第二,因为它只扫描一次表), 是否有可能使它更有效率 ? (BoolField = 1)实际上是一个variables(dyn sql),可以在表中包含任何where语句。

我在MS SQL 2005上运行。尝试了Quassnoi的例子,但没有按预期工作。

 select Status, * from WorkItems t1 where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' UNION select 'DELETED', * from WorkItems t1 where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) ) AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01) AND TimeStamp>'2009-02-12 18:00:00' AND NOT (BoolField05=1) 

也许这会做的伎俩。 我不能从这里testing它,但我不确定你正在使用什么版本的SQL。

联盟命令是你所需要的。 如果这不起作用,您可能需要改进您所处的环境。

使用案例进入select和使用在哪里closures一个或

这样的事情,我没有testing,但它应该工作,我认为…

 select case when CCC='D' then 'test1' else 'test2' end, * from table where (CCC='D' AND DDD='X') or (CCC<>'D' AND DDD='X') 

我想这就是你要找的东西:

 SELECT CASE WHEN BoolField05 = 1 THEN Status ELSE 'DELETED' END AS MyStatus, t1.* FROM WorkItems t1 WHERE (TextField01, TimeStamp) IN( SELECT TextField01, MAX(TimeStamp) FROM WorkItems t2 GROUP BY t2.TextField01 ) AND TimeStamp > '2009-02-12 18:00:00' 

如果你在Oracle或MS SQL 2005及以上版本,那么你可以这样做:

 SELECT * FROM ( SELECT CASE WHEN BoolField05 = 1 THEN Status ELSE 'DELETED' END AS MyStatus, t1.*, ROW_NUMBER() OVER (PARTITION BY TextField01 ORDER BY TimeStamp DESC) AS rn FROM WorkItems t1 ) to WHERE rn = 1 

,效率更高。

 select t1.* from (select * from TABLE Where CCC='D' AND DDD='X') as t1, (select * from TABLE Where CCC<>'D' AND DDD='X') as t2 

另一种方法来做到这一点!