TSQL:条件查询

时间:2016-09-01 19:14:53

标签: sql sql-server tsql

我有下表:

| RoomID | OrderID | Occupancy | rn |
+--------+---------+-----------+----+
| 01     | 101     | Vacant    | 1  |
| 01     | 102     | Occupied  | 2  |
| 01     | 103     | Occupied  | 3  |
| 01     | 104     | Vacant    | 4  |
| 02     | 201     | Vacant    | 1  |
| 02     | 202     | Occupied  | 2  |
| 02     | 203     | Vacant    | 3  |
| 03     | 301     | Vacant    | 1  |
| 03     | 302     | Occupied  | 2  |
| 03     | 303     | Occupied  | 3  |
| 03     | 304     | Occupied  | 4  |
| 04     | 401     | Occupied  | 1  |
| 04     | 402     | Occupied  | 2  |
| 04     | 403     | Vacant    | 3  |
| 04     | 404     | Occupied  | 4  |

我需要将满足以下所有要求的RoomID标记为“是”,如果一个或多个要求未满足为“否”,则需要:

  • rn = 1时Occupancy空置
  • rn = 2时Occupancy被占用
  • 任何大于2的rn(3,4,5 ..)都有Occupancy空缺

结果应如下所示:

| RoomID | OrderID |
+--------+---------+
| 01     | Yes     |
| 02     | Yes     |
| 03     | No      |
| 04     | No      |

我的印象是这很简单,但我现在看不到它,请提前感谢您的帮助!

5 个答案:

答案 0 :(得分:1)

构建于'是'> '不'

 select RoomId, 
        min(case when rn<>2 and Occupancy='vacant' 
                 or rn=2 and Occupancy='Occupied' 
            then 'Yes' else 'No' end) res
 from  myTable
 group by RoomId

答案 1 :(得分:1)

使用CASE计算每行的规则 当该规则的最小值(按room_id分组)为0时,其中至少有1个没有遵循该规则。

SELECT RoomID,
IIF(MIN(
    CASE 
    WHEN rn <> 2 AND Occupancy = 'Vacant' THEN 1
    WHEN rn = 2 AND Occupancy = 'Occupied' THEN 1 
    ELSE 0
    END)=0,'No','Yes') as OccupancyRule
FROM RoomOccupancyTable
GROUP BY RoomID;

答案 2 :(得分:0)

您可以使用条件聚合来检查每个条件。

with roomquery as (
     select RoomId, 
            min(case when rn<>2 and Occupancy='vacant' then 1 else 0 end) cond1,
            min(case when rn=2 and Occupancy='Occupied' then 1 else 0 end) cond2
     from rooms r
     group by RoomId)
select RoomId, 
       case when Cond1=1 and Cond2=1 then 'Yes' else 'No' end Status
from roomquery

注意:您可以重写它并只使用一个条件或前夕完全删除CTE(带语句),但我相信这更具可读性和可维护性。

答案 3 :(得分:0)

我想这会对你有帮助。

SELECT RoomID,
CASE WHEN ((rn = 1 OR rn > 2) AND Occupancy = 'Vacant') AND (rn = 2 AND Occupancy = 'Occupied') THEN 'Yes' ELSE 'No' END
FROM Table_Name    

答案 4 :(得分:0)

这是另一个答案,它计算子查询中每个RoomID的违规次数,然后相应地打印“是”或“否”:

SELECT sub.roomid,
CASE WHEN sum(sub.orderid_no) IS NOT NULL THEN 'No'
ELSE 'Yes'
END AS orderID
FROM
(SELECT roomid, 
CASE WHEN rn = 1 AND occupancy = 'occupied' THEN 1
WHEN rn = 2 AND occupancy = 'vacant' THEN 1
WHEN rn > 2 AND occupancy = 'occupied' THEN 1
END AS orderid_no
FROM T) sub
GROUP BY sub.roomid

在这里测试:http://sqlfiddle.com/#!9/d9d467/14

另外,我认为上面的输出是错误的。根据您的数据,RoomID 01应该具有OrderID“No”