簡體   English   中英

T-SQL:條件存在分組

[英]T-SQL: Conditional Existential grouping

我需要把所有的Room_IDsTABLE_A其中兩個2以上的最后Status的每個實例的Room_IDs是連續空置(相對於Inspection_Date ),並在不存在TABLE_B

這是我用作示例的簡化表:

TABLE_A

  Room_Id   Status    Inspection_Date
  -------------------------------------
    1        vacant      5/15/2015
    2        occupied    5/21/2015
    2        vacant      1/19/2016
    1        occupied   12/16/2015
    4        vacant      3/25/2016
    3        vacant      8/27/2015
    1        vacant      4/17/2016
    3        vacant     12/12/2015
    3        vacant      3/22/2016
    4        occupied    2/2/2015
    4        vacant      3/24/2015

TABLE_B

  Room_Id   Status    Inspection_Date
  ------------------------------------
    1        vacant       5/15/2015
    2        occupied     5/21/2015
    2        vacant       1/19/2016
    1        vacant      12/16/2015
    1        vacant       4/17/2016

我的結果應如下所示:

   Room_Id  Status  Inspection_Date
   ---------------------------------
    3       vacant      8/27/2015
    3       vacant     12/12/2015
    3       vacant      3/22/2016
    4       occupied    2/2/2015
    4       vacant      3/24/2015
    4       vacant      3/25/2016

這是模式:

CREATE TABLE TABLE_A (`Room_Id` int, 
                      `Status` varchar(55), 
                      `Inspection_Date` varchar(55)
                     );

INSERT INTO TABLE_A (`Room_Id`, `Status`, `Inspection_Date`)
VALUES  (1, 'vacant',      '5/15/2015'),
        (2, 'occupied',    '5/21/2015'),
        (2, 'vacant',      '1/19/2016'),
        (1, 'occupied',   '12/16/2015'),
        (4, 'vacant',      '3/25/2016'),
        (3, 'vacant',      '8/27/2015'),
        (1, 'vacant',      '4/17/2016'),
        (3, 'vacant',     '12/12/2015'),
        (3, 'vacant',      '3/22/2016'),
        (4, 'occupied',       '2/2/2015'),
        (4, 'vacant',      '3/24/2015');

CREATE TABLE TABLE_B (`Room_Id` int, 
                      `Status` varchar(55),         
                      `Inspection_Date` varchar(55)
                     );

INSERT INTO TABLE_B (`Room_Id`, `Status`, `Inspection_Date`)
VALUES
        (1, 'vacant',      '5/15/2015'),
        (2, 'occupied',    '5/21/2015'),
        (2, 'vacant',      '1/19/2016'),
        (1, 'vacant',      '12/16/2015'),
        (1, 'vacant',      '4/17/2016'),;

這將根據樣本數據提供您要尋找的結果。 ps感謝您包括create table和insert語句。

With cteA As
(
Select *, Row_Number() Over (Partition By Room_ID, Status Order By Inspection_Date Desc) RowNum From Table_A 
)
Select * From Table_A Where Room_Id In
(
Select Room_Id 
    From cteA
    Where Room_Id Not In (Select Room_Id From Table_B) 
        And Status = 'vacant' And RowNum > 1 
)
    Order By Room_Id, Inspection_Date

考慮這種方法:

with Rooms as (
    select
        Room_Id, Status,
        row_number() over (partition by Room_Id order by Inspection_Date desc) as rn
    from TABLE_A
), Candidates as (
    select Room_Id from Rooms group by Room_Id
    having sum(case when rn in (1, 2) and Status = 'vacant' then 1 else null end) = 2
)
select * from TABLE_A
where Room_Id in (select Room_Id from Candidates except select Room_Id from TABLE_B)
order by Room_Id, Inspection_Date desc

在此處查看運行中的查詢: http : //rextester.com/VXBRFF91880

其他方式:

;WITH cte AS (
SELECT DISTINCT a.Room_Id,
        COUNT(a.Inspection_Date) OVER(PARTITION BY a.Room_Id,a.[Status]  ORDER BY a.[Status]) as d
FROM TABLE_A a
FULL OUTER JOIN TABLE_B b
    ON a.Room_Id = b.Room_Id and a.Inspection_Date = b.Inspection_Date
WHERE b.Room_Id IS NULL and a.[Status] = 'vacant'
)

SELECT a.*
FROM cte c
INNER JOIN TABLE_A a
    ON a.Room_Id = c.Room_Id

輸出:

Room_Id Status      Inspection_Date
4       vacant      3/25/2016
3       vacant      8/27/2015
3       vacant      12/12/2015
3       vacant      3/22/2016
4       occupied    2/2/2015
4       vacant      3/24/2015

所有答案在一定程度上都是正確的,但是從不給我Room_IDs的每個實例的最后兩個作為Status空:

我找到了答案

         WITH lastDate AS ( SELECT Room_ID  ,MAX(Inspection_Date) AS [date]
                        FROM TableA
                        GROUP BY Room_ID), 
          prevLastDate AS ( SELECT a.Room_ID  ,MAX(Inspection_Date) AS [date]
                            FROM TableA a
                            INNER JOIN lastDate ON a.Room_ID = lastDate.Room_ID and a.Inspection_Date < lastDate.[date]
                            GROUP BY a.Room_ID), 
          lastDateVacant AS ( SELECT Room_ID   
                              FROM TableA
                              WHERE Room_ID IN ( SELECT Room_ID FROM lastDate) 
                              AND Inspection_Date IN ( SELECT [date] FROM lastDate) 
                              AND Status = 'Vacant'),
          prevLastDateVacant AS ( SELECT Room_ID   
                                  FROM TableA
                                  WHERE Room_ID IN ( SELECT Room_ID FROM prevLastDate) 
                                  AND Inspection_Date IN ( SELECT [date] FROM prevLastDate) 
                                  AND Status = 'Vacant')

    SELECT a.* 
    FROM TableA a 
    INNER JOIN lastDateVacant 
        ON a.Room_ID = lastDateVacant.Room_ID
    INNER JOIN prevLastDateVacant 
        ON a.Room_ID = prevLastDateVacant.Room_ID
    LEFT OUTER JOIN preservation.. AS b
        ON a.Room_ID = b.Room_ID    
    WHERE b.Room_ID IS NULL 
    ORDER BY a.Room_ID ASC, a.Inspection_Date DESC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM