2017-01-30 68 views
0

我试图删除以下查询的工会全部。如何删除union all?

DECLARE @TEMP TABLE (ID INT,DESCR VARCHAR(20)) 
      INSERT INTO @TEMP 
      SELECT 1,'A' 
      UNION 
      SELECT 2,'B' 
      UNION 
      SELECT 3,'C' 
      UNION 
      SELECT 4,'D' 

      SELECT DESCR,ID FROM @TEMP 
      WHERE DESCR NOT IN ('A','B') 
      UNION ALL 
      SELECT 'A+B',SUM(ID) FROM @TEMP 
      WHERE DESCR IN ('A','B') 

是否有一个建议,而不是使用UNION ALL

+5

为什么你要做到这一点,你实际上是希望能实现吗?你不清楚你想要做什么以及为什么。请添加您所需的输出。 – Tanner

+0

顺便说一下,添加ID是一个有趣的想法。 –

+0

Hi @ThorstenKettner id只是一个名字,如果你有任何id问题,你可以使用值而不是id。 –

回答

1

您可以使用group bycase

SELECT (CASE WHEN DESCR IN ('A', 'B') THEN 'AB' 
      ELSE DESCR 
     END) as DESCR, SUM(ID) as ID FROM @TEMP 
FROM @TEMP 
GROUP BY (CASE WHEN DESCR IN ('A', 'B') THEN 'AB' 
       ELSE DESCR 
      END); 

这确实让两个重要的假设:

  • DESCR是唯一的,至少对于不包含的行和'B'
  • 'AB'不在数据中。

如果这些都是真的,你仍然可以做你想要的,但查询可能会更复杂一点(并且表可能需要一个唯一的ID)。

1

如果确保DESCR在表中不能为空,那么就没有NOT IN问题,我们不需要任何额外的空处理来模仿它。

你会做的是建立伪组。 A“组”为每一个非A/B记录和全部A/B记录的真实组:

select 
    max(case when descr in ('A','B') then 'A+B' else descr end) as descr, 
    sum(id) as id 
from @temp 
group by 
    case when descr in ('A','B') then 'A' else descr end, 
    case when descr in ('A','B') then 0 else id end; 

这个伪分组只能然而,当有表中没有重复(例如,两个记录E/5)。如果有的话,那么我们将不得不随时生成一个唯一的密钥。

编辑:为了完整起见:如果表中可以有重复,我们需要一个唯一的标识符。一个简单的解决方案是使用无证%%physloc%%。 (另一种方法是,我们与ROW_NUMBER创建行号从派生表中选择。)

group by 
    case when descr in ('A','B') then 'A' else descr end, 
    case when descr in ('A','B') then 0 else id end, 
    case when descr in ('A','B') then 0 else %%physloc%% end; 
0
SELECT DESCR, CASE WHEN DESCR = 'A+B' THEN SUM(ID) ELSE MAX(ID) END AS ID 
FROM (
     SELECT CASE WHEN DESCR IN('A', 'B') THEN 'A+B' ELSE DESCR END AS DESCR, ID 
     FROM @TEMP 
) a 
GROUP BY DESCR; 

http://rextester.com/FUTXBQ64727