[英]Select record if exist in one table, else select from another
我正在写一份报价报告。 报价表有一个副本来跟踪更改历史记录,因此每次有人更改报价表时,旧值都会保存在该历史表中。
我想在报表中包括一个名为“原始到期日”的字段,该字段将显示报价的原始到期日。 如果历史记录表中有一条记录,它应该从那里获得第一个到期日。 否则,它应该从原始表中获取截止日期。
这是我表中记录的一些示例。
表格1:
|ID | Order | Due Date |
|1 | C1234 | 15/01/2000 |
|2 | C1235 | 15/02/2000 |
|3 | C1236 | 15/03/2000 |
|4 | C1237 | 15/04/2000 |
历史记录表:
|ID | Order | Due Date |
|1 | C1234 | 02/01/2000 |
|2 | C1234 | 05/01/2000 |
|3 | C1236 | 05/03/2000 |
|4 | C1236 | 07/03/2000 |
预期成绩:
|ID | Order | Original Due Date |
|1 | C1234 | 02/01/2000 |
|2 | C1235 | 15/02/2000 |
|3 | C1236 | 05/03/2000 |
|4 | C1237 | 15/04/2000 |
这是我尝试过的代码,由于我的子查询返回的值超过1,因此无法正常工作。
select case when exists (select 1 from quoteheader qh inner join quoteheaderhistory qhh on QH.QH_RecordID = QHH.QH_RecordID)
then (select QHH.QH_RFQ_Date from quoteheader qh inner join quoteheaderhistory qhh on QH.QH_RecordID = QHH.QH_RecordID)
else QH.QH_RFQ_Date
end,
* from quoteheader qh inner join quoteheaderhistory qhh
on QH.QH_RecordID = QHH.QH_RecordID
这应该工作:
DECLARE @tblO TABLE(ID INT,[Order] VARCHAR(10),DueDate DATE);
INSERT INTO @tblO VALUES(1,'C1234','20000115'),(2,'C1235','20000215'),(3,'C1236','20000315'),(4,'C1237','20000415');
DECLARE @tblH TABLE(ID INT,[Order] VARCHAR(10),DueDate DATE);
INSERT INTO @tblH VALUES(1,'C1234','20000102'),(2,'C1234','20000105'),(3,'C1236','20000305'),(4,'C1236','20000307');
WITH MinHistoricalDates AS
(
SELECT MIN(DueDate) AS MinHistDat,[order]
FROM @tblH
GROUP BY [order]
)
SELECT orig.ID
,orig.[order]
,ISNULL(mhd.MinHistDat,orig.DueDate) AS DueDateResolved
FROM @tblO AS orig
LEFT JOIN MinHistoricalDates AS mhd ON mhd.[order]=orig.[order]
尝试:
select [Order],[DueDate] from quoteheader
where [Order] not in
(select [Order] from
(select [Order],MIN(DueDate) as DueDate
from quoteheaderhistory
group by [Order]) a
)
union all
select [Order],MIN(DueDate) as DueDate
from quoteheaderhistory
group by [Order]
尽管根据您的数据, join
答案可能更适合您
这是我在评论中谈论的内容:
DECLARE @A TABLE ([ID] INT, [Order] CHAR(5), [DueDate] DATE)
DECLARE @H TABLE ([ID] INT, [Order] CHAR(5), [DueDate] DATE)
INSERT INTO @A VALUES
(1, 'C1234', '01/15/2000'),
(2, 'C1235', '02/15/2000'),
(3, 'C1236', '03/15/2000'),
(4, 'C1237', '04/15/2000')
INSERT INTO @H VALUES
(1, 'C1234', '01/02/2000'),
(2, 'C1234', '01/05/2000'),
(3, 'C1236', '03/05/2000'),
(4, 'C1236', '03/07/2000')
SELECT
[header].[ID],
[header].[Order],
[DueDate] = ISNULL(MIN([history].[DueDate]), MIN([header].[DueDate]))
FROM
@A [header]
LEFT JOIN @H [history] ON [header].[Order] = [history].[Order]
GROUP BY
[header].ID, [header].[Order];
编辑: 尽管如此,Shnugo的答案有一个更好的执行计划。 和那个一起去。
另外,您也可以进行left join
并使用MIN
窗口函数版本来实现结果:
select distinct
t1.id,
t1.[order],
COALESCE(min(ht.Due_Date) OVER (partition by t1.[order] order by t1.id)
,min(t1.due_date) OVER (partition by t1.[order] order by t1.id)) as Original Due Date
from table1 t1
left join history_table ht on ht.[Order] = t1.[Order];
尝试这个:
SELECT _order, min(due_date) as due_date
FROM history JOIN table1 USING (_order)
GROUP BY _order
此解决方案会忽略ID,但是您可以在获取适当的值后轻松生成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.