TSQL:条件查询问题

TSQL : conditional query issue

我需要创建一个标志来标识满足以下条件的所有 Room_IDs

这是一个简化的 table (tableX) 我用的例子是:

 **Hotel_ID  Room_Id     Status**
      1         1        vacant          
      1         2        qc-occupied  
      1         3        vacant          
      2         1        occupied       
      2         2        qc-vacant       
      2         3        vacant          
      3         1        qc-vacant       
      4         1        vacant         
      4         2        occupied        
      4         3        qc-vacant
      5         1        vacant 

我需要以下结果:

 **Hotel_ID  Room_Id     Status         flag**
      1         1        vacant          0
      1         2        qc-occupied     0
      1         3        vacant          0 
      2         1        occupied        0
      2         2        qc-vacant       1
      2         3        vacant          1
      3         1        qc-vacant       0
      4         1        vacant          0
      4         2        occupied        0
      4         3        qc-vacant       0
      5         1        vacant          0

提前致谢!

这是将需求字面翻译成相当不优雅的代码。它当然可以改进,例如通过删除您的第一个要求("qc-" present.),因为它隐含在其他两个要求中。第二个要求隐含在第三个中,允许另一个改进。

-- Sample data.
declare @TableX as Table ( Hotel_Id Int, Room_Id Int, Stat VarChar(16) );
insert into @TableX ( Hotel_Id, Room_Id, Stat ) values
  ( 1, 1, 'vacant' ), ( 1, 2, 'qc-occupied' ), ( 1, 3, 'vacant' ), 
  ( 2, 1, 'occupied' ), ( 2, 2, 'qc-vacant' ), ( 2, 3, 'vacant' ), 
  ( 3, 1, 'qc-vacant' ),
  ( 4, 1, 'vacant' ), ( 4, 2, 'occupied' ), ( 4, 3, 'qc-vacant' ), 
  ( 5, 1, 'vacant' );
select * from @TableX;

-- Literal translation of requirements.
declare @False as Bit = 0, @True as Bit = 1;
select Hotel_Id, Room_Id, Stat,
  QC_In_Hotel, QC_And_NonQC_In_Hotel, QC_Precedes_NonQC_In_Hotel,
  case when QC_In_Hotel = @True and QC_And_NonQC_In_Hotel = @True and
    QC_Precedes_NonQC_In_Hotel = @True then @True else @False end as Flag
  from (
    select Hotel_Id, Room_Id, Stat,
      -- Req: a "Qc-" Status is present within one Hotel_ID.
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and I.Stat like 'qc-%' )
        then @True else @False end as QC_In_Hotel,
      -- Req: the "Qc-" Status has a corresponding non "Qc-" Status (e.g. 'qc-occupied' & 'occupied').
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and
          ( ( I.Stat like 'qc-' + O.Stat ) or ( O.Stat like 'qc-' + I.Stat ) ) )
        then @True else @False end as QC_And_NonQC_In_Hotel,
      -- Req: the "Qc-" Status has to have a to have a smaller Room_ID than the non "Qc-" Status.
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and
          ( ( I.Room_Id < O.Room_Id and I.Stat like 'qc-' + O.Stat ) or
            ( O.Room_Id < I.Room_Id and O.Stat like 'qc-' + I.Stat ) ) )
        then @True else @False end as QC_Precedes_NonQC_In_Hotel
      from @TableX as O ) as PH
  order by Hotel_Id, Room_Id;