繁体   English   中英

如果一个表中存在,则选择记录,否则从另一个表中选择

[英]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];

SQL小提琴演示

尝试这个:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM