【问题标题】:Assign correct Responsible person from JSON format column based on Service Date根据服务日期从 JSON 格式列中分配正确的负责人
【发布时间】:2022-02-06 04:38:52
【问题描述】:

附注之前的帖子已被删除,希望这次能接触到更多的人。

我有庞大的历史数据集,我需要为与客户关联的所有行的服务日期分配值(ResponsibleName - 来自 JSON 格式列)到一个新的“责任”列。

每个客户可以在特定日期范围内拥有唯一的负责人(JSON 列):

  1. 如果代码列包含主管,则将此员工分配给仅作为责任人的关联行。
  2. 最后,如果代码列包含员工,则将 JSON 列(针对特定日期范围)中的关联负责人分配给负责人

我的第一步没有问题,但是我找不到实现第二(最后)语句的解决方案。

与客户表连接的原始历史表:

SELECT h.Id,
       h.ServiceDate
       h.ClientId,
       cl.ClientName,
       h.EmployeeName,
       cl.ResponsibleJSON,
       h.Codes
FROM History AS h
JOIN ClientTable AS cl
   ON (h.ClientId = cl.ClientId)

该表的输出:

Id ServiceDate ClientId ClientName EmployeeName ResponsibleJSON Codes
1 2020-05-06 123 John Smith Chris Evans [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Employee, Office
2 2020-05-08 123 John Smith Tom Holland [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Supervisor, Remote
3 2020-05-11 123 John Smith Chris Evans [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Employee, Office
4 2020-05-15 123 John Smith Thomas Anderson [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Employee, Office
5 2020-06-10 123 John Smith Tom Holland [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Supervisor, Office
6 2020-06-17 123 John Smith Thomas Anderson [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Employee, Remote
7 2020-06-22 123 John Smith Elon Mask [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Employee, Remote
8 2020-07-01 123 John Smith Tom Holland [{"ResponsibleName":"Kevin Costner","ResponsibleStartDate":"2019-02-14","ResponsibleEndDate":"2020-05-31"},{"ResponsibleName":"Tom Cruise", "ResponsibleStartDate":"2020-06-01","ResponsibleEndDate":null}] Supervisor, Remote

我已经为所有客户端创建了包含所有 JSON 数据的表:

SELECT  c.ClientId,
        c.ClientFullName,
        c.ResponsibleJSON,
        JSON_VALUE(X.VALUE,'$.ResponsibleName') AS ResponsibleName,
        JSON_VALUE(X.VALUE,'$.ResponsibleStartDate') AS ResponsibleStartDate,
        ISNULL(JSON_VALUE(X.VALUE,'$.ResponsibleEndDate'), '2999-12-31') AS ResponsibleEndDate

FROM ClientTable AS c
CROSS APPLY OPENJSON(c.ResponsibleJSON) AS X
ORDER BY c.ClientFullName, ResponsibleStartDate

现在我需要以某种方式将它们组合起来以生成下面的列:

期望的输出:

Responsible
Kevin Costner
Tom Holland
Kevin Costner
Kevin Costner
Tom Holland
Tom Cruise
Tom Cruise
Tom Holland

我需要帮助的代码可以在下面找到。 我不知道我是否可以在 CASE 语句中 OUTER APPLY 并且我认为 JOIN 应该是 ON ClientId 并检查 ServiceDate 是否在 ResponsibleStartDate 和 ResponsibleEndDate 之间。

SELECT h.Id,
       h.ServiceDate
       h.ClientId,
       cl.ClientName,
       h.EmployeeName,
       cl.ResponsibleJSON,
       h.Codes,

       CASE
          WHEN h.Codes LIKE '%Supervisor%' THEN h.EmployeeName --- 1st statement
          WHEN --- here should be the second statement. I don't know how to implement it.
       END AS Responsible

FROM History AS h
JOIN ClientTable AS cl
   ON (h.ClientId = cl.ClientId)

【问题讨论】:

  • “之前的帖子被删除了,希望这次能接触到更多的人。” 转发一个问题一般不会很受欢迎。如果你想让一个问题得到更多关注,请赏金。
  • 谢谢你的建议,@Laurnu。不知道。下次会做
  • 这是您第二次删除并转发。小心,你可能会被自动封禁
  • @Charlieface,我会记住的。没有更多的删除。谢谢
  • 我不明白逻辑:如果Tom Holland 不存在于ResponsibleJSON 中,它们如何最终出现在结果中?所有这些列发生了什么,您只显示预期结果中的一列,它与第一个表有何关联?

标签: json sql-server date join case


【解决方案1】:

Codes 列不包含Supervisor 时,您似乎只想查找JSON。下面的查询应该做你想做的事:

SELECT
  c.Id,
  c.ServiceDate,
  c.ClientId,
  c.ClientName,
  c.EmployeeName,
  c.Codes,
  Supervisor =
      CASE WHEN c.Codes LIKE '%Supervisor%' THEN c.EmployeeName
      ELSE (
          SELECT TOP (1)
            j.ResponsibleName
          FROM OPENJSON(c.ResponsibleJSON)
            WITH (
              ResponsibleName nvarchar(100),
              ResponsibleStartDate date,
              ResponsibleEndDate date
            ) j
          WHERE c.ServiceDate >= j.ResponsibleStartDate
            AND (j.ResponsibleEndDate IS NULL OR c.ServiceDate <= j.ResponsibleEndDate)
      )
      END
FROM ClientTable c;

db<>fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多