简体   繁体   English

涉及CTE,CASE和子查询的SQL Server查询

[英]SQL Server query involving CTEs, CASE, and subqueries

These are the data sets that I am using: 这些是我正在使用的数据集:

create table test (
masterid int, 
subID varchar(100),
entrydate datetime
)

insert into test
values 
(1,'A','5/1/14'),
(1,'B','4/1/14'),
(1,'C','3/1/14'),
(2,'D','4/1/14'),
(2,'E','6/1/14'),
(2,'F','2/1/14'),
(3,'A','12/1/13'),
(3,'B','1/1/14'),
(3,'E','2/1/14');


Create table test2 (
subID varchar(50),
corptype varchar(50)
)

insert into test2 
values
('A','N'),
('B','N'),
('C','Y'),
('D','Y'),
('E','N'),
('F','N')

    select t1.masterid
           , t1.subID 
           , t2.corptype
           , t1.entrydate
    from   test t1
           join test2 t2 on t1.subID = t2.subID 

I have to write a query with the following requirements: 我必须编写一个具有以下要求的查询:

1.) For a given masterID, if the corptype of any of the subIDs is 'Y', then select the masterID, subID, corptype, and entrydate. 1.)对于给定的masterID,如果任何子ID的实体类型为“ Y”,则选择masterID,subID,实体类型和输入日期。

2.) For a masterID that has no 'Y' for any of the subIDs, I need to select the masterID, subID, corptype, and entrydate having the most recent entrydate. 2.)对于任何子ID都不为“ Y”的masterID,我需要选择具有最新进入日期的masterID,subID,实体和进入日期。

Please assume that the list of masterIDs is too long to identify all Y's first, then select 'N's that don't have a masterID in the list of Y's. 请假设masterID列表太长,无法首先标识所有Y,然后选择Y列表中没有masterID的“ N”。

My attempt: 我的尝试:

    WITH cte AS
                (
                   SELECT *,
                         ROW_NUMBER() OVER (PARTITION BY t1.masterid ORDER BY t1.entrydate DESC) AS rn
                   FROM test t1
                )

    select CASE (test2.corptype)
    when 'Y'

    THEN

                (select t1.masterid
                        , t1.subID 
                        , t2.corptype
                        , t1.entrydate
                from test t1
                join test2 t2 on t1.subID = t2.subID 
                where t2.corptype = 'Y')

    ELSE            

                (SELECT cc.masterid, cc.subID, t2.corptype, cc.entrydate
                FROM cte cc
                join test2 t2 on cc.subID = t2.subID 
                WHERE rn = 1
                and t2.corptype = 'N'
                --order by cc.entrydate
                )

    END

The final output should be: 最终输出应为:

masterid    subID corptype    entrydate
1           C      Y            00:00.0
2           D      Y            00:00.0
3           E      N            00:00.0

If I understand correctly, this is a strange sort of prioritization problem. 如果我正确理解,这是一个奇怪的优先级问题。 It seems strange because the priorities are coming from two tables. 似乎很奇怪,因为优先级来自两个表。 First corptype from test2 and then entrydate from test . 首先是test2体型,然后是test entrydate

You can solve this genre of problems using row_number() . 您可以使用row_number()解决这类问题。 If I'm correct, then this may do what you want: 如果我是正确的,那么这可以做你想要的:

select t.masterId, t.smallId, t.corptype, t.entrydate
from (select t.masterID, t.smallID, t2.corptype, t.entrydate,
             row_number() over (partition by t.masterId
                                order by (case when t2.corptype = 'Y' then 0 else 1 end),
                                         t.entrydate desc
                              ) as seqnum
     from test t join
          test2 t2
          on t.smallid = t2.smallid
    ) t
where seqnum = 1;
Select a.MasterId, coalesce(b.subId, c.subId),
   a.entrydate,  
From test a
   Left join test2 b 
      on b.subID = a.subID
         and b.corptype = 'Y'
  join test2 c 
      on c.subID = a.subID
         and a.entryDate =
             (Select Max(entryDate)
              from test 
              where MasterId = a.MasterId)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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