我如何将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 
另一种方法来做到这一点!