【问题标题】:How to aggregate over two columns with a condition on the secondary one?如何在第二列的条件下聚合两列?
【发布时间】:2019-02-19 20:41:50
【问题描述】:

初学者问题 - 不知道如何简洁地表达问题(因此为什么我在档案中找不到类似的东西?),所以让我们用一个虚构的例子来说明:

1) 您拥有一家连锁酒店,并想了解您的所有酒店总共有多少客房仅供成年男性入住。

2) 同上,但无论出于何种原因,您还想分别找出单身男性和 2 名以上男性占用的房间数量。

您有一个表格,其中包含以下列:

| guest_ID | hotel_name | room_ID | gender |

因此,[guest_ID] 是一些 ID 列,其中包含每个入住酒店的人的唯一 ID。 [hotel_name] 是每个分店的名称,应该与查询无关。 [room_ID] 是每个分支中的房间号,但它是唯一的,因此 The Pink Flamingo 中的房间 237 与 The Stanley 中的房间 237 具有不同的 ID,一个 int 或其他。假设 [gender] 可以采用“男性”、“女性”或“儿童”的值。

我想确保我不会意外从结果中的“混合”房间中挑选客人行。

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 你的数据库设计得非常简陋。缺少预订的时间间隔/帧。 imho [Hotel Room Bookings Guest] 应该是自己的表/实体
  • 我们可以为您提供帮助,但我们需要努力自己解决这个问题。为此,您将需要几个子查询,此外,添加 create table + insert 语句将有助于人们帮助您解决问题。
  • 抱歉,我只是想看看是否有办法进行这种聚合。我需要解决的真正查询要复杂得多,涉及 4-5 个表。进入这样的细节只会让人感到困惑。但到目前为止,在我的努力中,如果我们翻译,我确实得到了一个包含混合房间的房间计数,也许还有一些双重计数(来自非 PK 列的连接)。我敢肯定,数据库结构可能会更好。不是我的设计。不适用于此查询。不过,这无济于事,因为我仍然希望获得数据。如果你不想帮忙,那就不要。没关系。

标签: sql-server tsql


【解决方案1】:

在您所有的酒店中总共有多少间客房仅供成年男性入住

SELECT 
    COUNT(*) AS TOTAL_ROOMS
FROM
(
    SELECT 
        room_ID
    FROM 
        MyTable
    OUTER APPLY 
    ( 
        SELECT CASE WHEN gender = 'male' THEN 1 ELSE 0 END AS IS_MALE
    ) AS T
    GROUP BY 
        room_ID 
    HAVING 
        SUM(T.IS_MALE)/COUNT(*) = 1
) AS ROOMS

同上,但无论出于何种原因,您还想知道单身男性入住的房间数量

SELECT 
    COUNT(*) AS TOTAL_ROOMS
FROM
(
    SELECT 
        room_ID
    FROM 
        MyTable
    OUTER APPLY 
    ( 
        SELECT CASE WHEN gender = 'male' THEN 1 ELSE 0 END AS IS_MALE
    ) AS T
    GROUP BY 
        room_ID 
    HAVING 
        SUM(T.IS_MALE)/COUNT(*) = 1 AND COUNT(*) = 1
) AS ROOMS

由 2 位以上的男性组成

SELECT 
    COUNT(*) AS TOTAL_ROOMS
FROM
(
    SELECT 
        room_ID
    FROM 
        MyTable
    OUTER APPLY 
    ( 
        SELECT CASE WHEN gender = 'male' THEN 1 ELSE 0 END AS IS_MALE
    ) AS T
    GROUP BY 
        room_ID 
    HAVING 
        SUM(T.IS_MALE)/COUNT(*) = 1 AND COUNT(*) >= 2
) AS ROOMS

【讨论】:

  • 我将 SUM(T.IS_MALE)/COUNT(*) = 1 更改为 SUM(T.IS_MALE) = COUNT(*) 只是因为看到除法让我担心 0 除法错误(即使它不会发生在 group by 中)。也可以将SUM(T.IS_MALE) 替换为SUM(CASE WHEN gender = 'male' THEN 1 END) 并避免APPLY。
  • 感谢四月雨! (以及 EzLo 的评论。)我敢肯定,对于精通 SQL 的人来说超级简单,但对我真的很有帮助。优雅(!)我在别处询问,我们讨论了一些解决方案,例如带有计数器的临时表,和/或一个新的关系表来处理结构混乱。可能会起作用,但不会有那么时尚。
猜你喜欢
  • 2018-11-30
  • 1970-01-01
  • 2021-07-05
  • 2020-11-03
  • 2015-08-17
  • 2021-04-09
  • 1970-01-01
  • 2021-12-10
  • 2023-04-02
相关资源
最近更新 更多