【问题标题】:How to write complex SQL query for my given data?如何为我的给定数据编写复杂的 SQL 查询?
【发布时间】:2020-12-08 15:42:06
【问题描述】:

如何编写复杂的 SQL 查询?

以下信息是使用不同服务的用户的旧数据,包括特定Service_Area 和Service_Sector 的服务状态和最后更改日期。 所有用户都在使用多项服务,其中一些服务对于特定的 Service_Area 和 Service_Sector 仍然处于活动状态。

文字要求:

当用户的服务处于非活动状态时,我需要选择所有列,并且只记录该用户的特定 Service_Area 和 Service_Sector。

如前所述,用户可以在 Service_Area 和 Service_Sector 组合上拥有多个服务。如果用户的 Service_Area 和 Service_Sector 上有多个服务,那么如果所有服务都处于非活动状态,我们需要选择最后更改的记录(我的意思是,当两者之间有一条服务状态为活动的记录时,那么我们无法从该用户的该 Service_Area 和 Service_Sector 中选择任何用户数据。

场景:

案例 1: 当有 5 个服务都处于非活动状态时,我们需要选择最后更改的记录。

案例 2: 当 5 个服务中至少有一个处于活动状态的服务时,我们无法从该用户的特定 Service_Area 和 Service_Sector 中选择该用户数据。

案例 3 当该用户的 Service_Area 和 Service_Sector 上只有一个服务时,它处于非活动状态,该记录也会被选中。

关于表:

Location_Code、User_Id、Service_Area、Service_Sector、Service 将始终进行唯一的组合。而且这个组合上可能有很多服务Location_Code、User_Id、Service_Area、Service_Sector。

请在下面找到带有结果表的示例表(显示预期输出)。

示例表:

Loc_Code User_Id Service_Area Service_Sector Service Status Last_Changed
101 1001 C 1 PAINT INACTIVE 11/28/2020
101 1002 A 1 WOOD INACTIVE 12/7/2020
101 1002 A 1 CLEANING ACTIVE 11/23/2020
101 1002 A 1 PEST INACTIVE 12/7/2020
101 1002 A 2 LIGHT INACTIVE 12/7/2020 `
101 1002 B 2 AC INACTIVE 11/28/2020
101 1002 B 2 HEATER INACTIVE 11/30/2020

结果表:

总共选择了 3 条记录。

  1. 当用户在特定 Service_Area 和 Service_Sector 上处理单个非活动服务时选择第一条记录。
  2. 之所以选择第二条记录,是因为 Location_Code、User_Id、Service_Area、Service_Sector 组合上只有一项服务,处于非活动状态。
  3. 选择的第三条记录是因为Location_Code、User_Id、Service_Area、Service_Sector组合列表2-非活动服务,选择了最后一次更改的服务。
Loc_Code User_Id Service_Area Service_Sector Service Status Last_Changed
101 1001 c 1 PAINT INACTIVE 11/28/2020
101 1002 A 2 LIGHT INACTIVE 12/7/2020
101 1002 B 2 HEATER INACTIVE 11/30/2020

【问题讨论】:

  • 欢迎来到 SO。请阅读How to Ask。不要发布指向表格数据图像的链接。编辑问题并将示例数据放入其中。另外,你有什么尝试?如果您希望得到帮助,您需要在这里付出一些努力。谢谢
  • 我投票结束这个问题,因为 - OP 没有显示任何解决问题的尝试
  • 对不起,我试着按照你的逻辑,但我做不到。请将您的表格作为文本发布,最好是作为 dbfiddle。请让选择标准更明显——“所有服务状态为非活动的记录”是有道理的,但我不明白“曲折”
  • 是的,您解释的内容不支持您显示为所需输出的内容

标签: mysql sql database


【解决方案1】:

我认为这就是你想要的,你可以使用 ctewindow function 来实现:

WITH cte AS (
    SELECT * 
      , RANK() OVER (PARTITION BY LOC_N, U_NUM, SRV_AREA, SRV_SEC ORDER BY CHG_DATE desc)  AS _rank
        FROM yourtablename
    )

SELECT 
   LOC_N, U_NUM, SRV_AREA, SRV_SEC, SRV, STATUS, CHG_DATE 
FROM cte
WHERE 
   cte.STATUS = 'INACTIVE'
   AND cte._rank = 1

如果您不需要显示 SRV 列,则该查询将如下所示:

SELECT
    LOC_N
    , U_NUM
    , SRV_AREA
    , SRV_SEC
    , STATUS
    , MAX(CHG_DATE) as CHG_DATE
FROM
    yourtablename
WHERE
    STATUS = 'INACTIVE'
GROUP BY
    LOC_N
    , U_NUM
    , SRV_AREA
    , SRV_SEC
    , STATUS;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多