【问题标题】:T-SQL if date is greater or equal to this date then return x if not return yT-SQL 如果日期大于或等于该日期,则返回 x 如果不​​返回 y
【发布时间】:2017-09-27 21:34:41
【问题描述】:

我有一个交易日期,需要从另一个表返回一个字段。

Table A  Visit    Bill     Transaction Date
          1         1          12/20/2016

如果代码日期在交易日期之后,我需要返回另一个代码表。

Table B   Bill   CodeID  Effective Code Date         Code
           1        A        9/1/2015                  ABCDE
           1        B        9/1/2015                  FGHI 
           1        C        9/1/2015                  JKLM
           1        A        10/01/2016                ZQMOP
           1        B        10/01/2016                XYZNP
           1        C        10/01/2016                EFGHI 

我如何得到这个结果?

 Vist   Bill  TransactionDate   CodeID     Code
 1       1       12/20/2016      A        ZQMOP
 1       1       12/20/2016      B        XYZNP
 1       1       12/20/2016      C        EFGHI 

【问题讨论】:

  • 到目前为止您尝试过什么?从上面的示例中,不应该返回任何一个,因为它们都不是在交易日期之后。
  • @Eric 对不起,我的意思是我需要返回 CodeID 和代码,其生效日期最接近交易日期。示例:由于交易日期是 2016 年 12 月 20 日,我需要 10/01/2016 代码。如果交易日期是 2015 年 9 月 2 日,我需要返回生效日期为 2015 年 9 月 1 日的代码。我还没有尝试过任何东西。我没有代码。
  • 你的第一张桌子;它只包含一个值吗?根据该表中的其他内容,您问题的各种答案可能会产生意想不到的行数。
  • @Xedni 表 A 是一样的。表 B 我忘记添加账单了。我已经添加了。

标签: sql-server tsql field lookup


【解决方案1】:

这是一种方法,但我想到了其他方法(例如使用 row_number)

前两个 CTE 只是设置您的数据。然后查询基本上提取10/01/2016 的所有内容。该日期由选择max(b.EffectiveCodeDate) 的子查询确定,该日期严格小于该账单的交易日期。

;with a as
(
    select visit = 1, bill = 1, transactiondate = cast('12/20/2016' as date)
), b (Bill, CodeId, EffectiveCodeDate, Code) as
(
              select 1, 'A', cast('9/1/2015' as date),'ABCDE'
    union all select 1, 'B', '9/1/2015','FGHI' 
    union all select 1, 'C', '9/1/2015','JKLM'
    union all select 1, 'A', '10/01/2016','ZQMOP'
    union all select 1, 'B', '10/01/2016','XYZNP'
    union all select 1, 'C', '10/01/2016','EFGHI' 
)
select *
from b
where b.EffectiveCodeDate = 
    (
        select max(b.EffectiveCodeDate)
        from b
        inner join a
            on a.Bill = b.Bill
            and b.EffectiveCodeDate < a.TransactionDate
    )

【讨论】:

    【解决方案2】:

    我认为下面的查询有效

    样本数据:

    create table #A (Visit int, Bill int, [Transaction Date] date)
    insert into #A values (1, 1, '12/20/2016')
    
    create table #B (Bill int, CodeID char(1),  [Effective Code Date] date, Code varchar(10))
    insert into #B values
    (1, 'A', '9/1/2015'  , 'ABCDE'),
    (1, 'B', '9/1/2015'  , 'FGHI' ),
    (1, 'C', '9/1/2015'  , 'JKLM' ),
    (1, 'A', '10/01/2016', 'ZQMOP'),
    (1, 'B', '10/01/2016', 'XYZNP'),
    (1, 'C', '10/01/2016', 'EFGHI')
    

    查询:

    ;with ct as (
        select *
        , ROW_NUMBER() over (partition by Bill, CodeID order by [Effective Code Date] desc) RN
        from #B
    )
    select #A.*, ct.CodeID, ct.Code
    from #A 
        inner join ct on ct.Bill = #A.Bill and ct.RN = 1
    

    【讨论】:

      【解决方案3】:

      我认为这会解决的:

      DECLARE @MinimumDiffrence int = (select Min(ABS(DATEDIFF(MILLISECOND,transaction_date,Effective_Code_Date))) 
                                      from A inner join B on A.Bill=B.Bill)
      select * 
      from A
      inner join B 
      on A.Bill = B.Bill
      where ABS(DATEDIFF(MILLISECOND,transaction_date,Effective_Code_Date)) = @MinimumDiffrence
      

      必须有一种方法,只需 1 个查询就可以做到这一点,我会努力找到它。

      【讨论】:

        【解决方案4】:

        试试这个,

        create table #A (Visit int, Bill int, [Transaction Date] date)
        insert into #A values (1, 1, '12/20/2016')
        
        create table #B (Bill int, CodeID char(1), 
         [Effective Code Date] date, Code varchar(10))
        insert into #B values
        (1, 'A', '9/1/2015'  , 'ABCDE'),
        (1, 'B', '9/1/2015'  , 'FGHI' ),
        (1, 'C', '9/1/2015'  , 'JKLM' ),
        (1, 'A', '10/01/2016', 'ZQMOP'),
        (1, 'B', '10/01/2016', 'XYZNP'),
        (1, 'C', '10/01/2016', 'EFGHI')
        
        select * from
        #A a 
            inner join #B b on b.Bill = a.Bill 
         where DATEDIFF(day,[Effective Code Date],[Transaction Date]) =
        (
        select min(DATEDIFF(day,[Effective Code Date],[Transaction Date])) MinDiff
        from #A a 
            inner join #B b on b.Bill = a.Bill 
        
        ) 
        
            drop table #A
            drop table #B
        

        【讨论】:

          【解决方案5】:

          我认为这种方法,使用CROSS APPLY 最接近您要解决的问题的描述:

          declare @ta table (Visit int not null, Bill int not null, TransactionDate date not null)
          insert into @ta (Visit,Bill,TransactionDate) values
          (1,1,'20161220')
          
          declare @tb table (Bill int not null, CodeID char(1) not null, 
                             EffectiveCodeDate date not null, Code varchar(5) not null)
          insert into @tb (Bill,CodeID,EffectiveCodeDate,Code) values
          (1,'A','20150901','ABCDE'),
          (1,'B','20150901','FGHI'),
          (1,'C','20150901','JKLM'),
          (1,'A','20161001','ZQMOP'),
          (1,'B','20161001','XYZNP'),
          (1,'C','20161001','EFGHI')
          
          select
              *
          from
              @ta a
                  cross apply
              (select *,ROW_NUMBER() OVER (PARTITION BY CodeID ORDER by EffectiveCodeDate desc) as rn
              from @tb b
              where
                  b.Bill = a.Bill and
                  b.EffectiveCodeDate < a.TransactionDate) p
          where
              rn = 1
          

          也就是说,对于表 B 中的每一行,以及每个不同的 CodeID 值,我们希望从表 A 中选择早于 TransactionDate 的最新行。

          结果:

          Visit       Bill        TransactionDate Bill        CodeID EffectiveCodeDate Code  rn
          ----------- ----------- --------------- ----------- ------ ----------------- ----- --------------------
          1           1           2016-12-20      1           A      2016-10-01        ZQMOP 1
          1           1           2016-12-20      1           B      2016-10-01        XYZNP 1
          1           1           2016-12-20      1           C      2016-10-01        EFGHI 1
          

          (作为练习将结果集缩减为您需要的列)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-20
            • 2016-02-22
            相关资源
            最近更新 更多