我在SQL Server中工作。我有三个表,TableA
,TableB
和TableMain
,包含Date
,StartTime
和FinishTime
列。
我必须编写一个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
答案 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
)。请注意我的列名,只需更改为您的列名称,这应该有效。