如何从SQL Server中的联接表中优先获取数据

时间:2016-10-13 15:11:10

标签: sql sql-server

我在SQL Server中工作。我有三个表,TableATableBTableMain,包含DateStartTimeFinishTime列。

我必须编写一个SQL语句,它必须从TableMain中提取这三个列值。如果TableA中存在相同的日期,则StartTime值应来自它,否则只需使用TableMain中的值。同样,如果FinishTime中存在TableB,则在最终输出中该值应替换TableMain中的值。

我想通过加入这三个表来实现。以下显示了这三个表中的数据以及最终的预期查询输出。

表A

Date        StartTime
10/14/2016  11:00 AM
10/16/2016  10:00 AM
10/18/2016  11:30 AM

表B

Date        FinishTime
10/15/2016  3:00 PM
10/16/2016  4:00 PM
10/17/2016  6:30 PM
10/18/2016  5:00 PM

TableMain

Date        StartTime   FinishTime
10/14/2016  8:00 AM     10:00 PM
10/15/2016  8:00 AM     10:00 PM
10/16/2016  8:00 AM     10:00 PM
10/17/2016  8:00 AM     10:00 PM
10/18/2016  8:00 AM     10:00 PM

期望的输出:

10/14/2016  11:00 AM    10:00 PM
10/15/2016  8:00 AM     3:00 PM
10/16/2016  10:00 AM    4:00 PM
10/17/2016  8:00 AM     6:30 PM
10/18/2016  11:30 AM    5:00 PM

2 个答案:

答案 0 :(得分:1)

COALESCE也可以在这里工作,没有所有CASE声明:

SELECT tablemain.date,
COALESCE(tablea.starttime, tablemain.starttime),
COALESCE (tableb.finishtime, tablemain.finishtime)
FROM tablemain
LEFT JOIN tablea
ON tablemain.date = tablea.date
LEFT JOIN tableb
ON tablemain.date = tableb.date

COALESCE获取系列中的第一个非NULL值。因此,如果表a中有开始日期,则需要这样做。如果没有,它将从表main开始。完成日期和表格b的逻辑相同。

答案 1 :(得分:0)

真的未经测试但是这样的事情:

SELECT
   t.DateVal,
   t.Start,
   t.Finish
FROM
(
SELECT
   tm.DateVal AS DateVal,
   CASE WHEN a.Start IS NOT NULL THEN a.Start ELSE tm.Start END AS Start,
   CASE WHEN b.Finish IS NOT NULL THEN b.Finish ELSE tm.Finish END AS Finish
FROM 
   TableMain tm
LEFT JOIN
   TableA a
ON
   a.DateVal = tm.DateVal
LEFT JOIN
   TableB b
ON
   b.DateVal = tm.DateVal
) t

这里的关键是你使用一些左连接,一个case语句和一个派生表结果(在这种情况下是t)。请注意我的列名,只需更改为您的列名称,这应该有效。