使用Union查询,从第一个表中获取数据并在UNION查询的其他部分使用它

时间:2018-03-06 11:03:35

标签: sql sql-server

我必须为以下场景编写查询:

Select Time, Column A, Column B
From Table A
UNION 
Select Time, Column X, Column Y
From Table B

两个查询的数据如下: 来自表A -

Time   |Column A |Column B|
Oct-17 | 20      | 10     |
Nov-17 | 25      | 15     |
Dec-17 | 40      | 30     |

表B

Time  |Column X  |Column Y|
Jan-18| 30       |15      |

预期产出:

Time   | Column A | Column B|
Oct-17 | 20       | 10      |
Nov-17 | 25       | 15      |
Dec-17 | 40       | 30      |
Jan-18 | 30/40    |15       |

当我们进行联合时,我需要Dec-17 A列值(表A)来计算1月18日的X列(表B)。我不想在查询的第二部分加入表A,因为我在这里只给出了虚拟数据,实际查询真的很大并且已经有很多表连接。 我尝试使用左连接,但它不起作用。任何人都可以帮助在这种情况下做什么。 提前谢谢。

3 个答案:

答案 0 :(得分:0)

使用 CTE 计算 tablea 的值,其值为 tableb

with cte as
(
    Select Time, [Column A], [Column B],1 as first
    From tablea
    union all
    Select Time, [Column X], [Column Y],2 as second
    From tableb
)

select time,
       case when first = 1 then cast([Column A] as varchar) else concat([Column A] ,  '/' ,
           (select top 1 [Column A] from cte where first = 1 order by time))
       end [Column A], [Column B] 
from cte c

答案 1 :(得分:0)

您可以使用lag()和一些条件逻辑函数,假设time以合理的格式存储:

select time,
       (case when lag(year(time)) over (order by time) <> year(time) over (order by time)
             then [Column A] + '/' + lag([Column A]) over (order by time)
             else [Column A]
        end) as [Column A],
       [Column B]
from ((Select Time, [Column A], [Column B]
       From tablea
      ) union all
      (Select Time, [Column X], [Column Y]
       From tableb
      )
     ) a;

这假设配对的逻辑是因为该行是一年中的第一行。当然,你可以只是一个更简单的表达,比如查看确切的时间。

答案 2 :(得分:0)

我使用临时表尝试了它,并且查询花费的时间更少,因此想到共享它。其他答案对我来说真的很有帮助。

Create Table ##TempTable
(
 Time varchar,
 [Column A] float,
 [Column B] float,
 first int,
 ID varchar
)
INSERT INTO ##TempTable
Select Time, [Column A], [Column B], first,ID
from
(
 Select Time, [Column A], [Column B],1 as first,ID
 From tablea
 union all
 Select Time, [Column X], [Column Y],2 as second,ID
 From tableb
)A

Select Time, 
CASE WHEN A.first = 1 THEN A.[Column A]  
ELSE (B.[Column A]/A.[Column A]) END [Column A],
[Column B]
From ##TempTable A
LEFT JOIN 
(SELECT TOP 1 * FROM ##TempTable WHERE first=1 ORDER BY ID DESC  ) B
ON A.ID >= B.ID