根据不同的标准和日期分配群组的逻辑

huangapple go评论137阅读模式
英文:

Logic of assigning a group based on different criteria with dates

问题

以下是翻译好的部分:

数据包括在指定日期服用补充剂(AABBC)的 ID

ID A AB B C
1 2021-01-01 2021-02-01 2021-03-01 2021-04-01
2 null 2021-06-01 null 2021-08-01
3 2021-09-01 null 2021-08-01 null
4 null null 2021-11-01 null
5 2021-09-01 2021-06-01 null null
6 2021-09-01 null 2021-11-01 2021-11-02
7 2021-09-01 2021-09-01 2021-11-01 2021-11-02
8 2021-09-01 null 2021-09-01 2021-11-02
9 2021-09-01 null 2021-09-01 2021-08-02
10 2021-09-01 null 2021-09-01 2021-07-02
11 2021-09-01 2021-09-01 null null
12 2021-08-01 2021-09-01 null null
13 2021-08-01 2021-09-01 null 2021-10-01
14 2021-08-01 null null 2021-09-01
15 2021-09-01 2021-12-01 null 2021-09-01
16 2021-10-01 null null 2021-09-01

补充剂 AB 包括补充剂 AB

我需要对每个 ID 进行分类,并在满足以下条件时获取 ID 服用 BAB 或两者一起的日期:

  1. 必须在服用 C(或 C IS NULL)之前服用 BAB
  2. 如果服用 B,则需要在服用 B 之前或同时服用 AAB。如果在服用 B 之前服用了 AB,则日期为 AB 的服用日期。当在服用 B 之前服用了 A 时,日期为 B 的服用日期。

此外,有时一个 ID 可以同时服用多种补充剂,这也是可以的。例如 ID 11 同时服用 AAB

当我查看表格时,很容易应用,但将其转化为逻辑形式不像我预期的那样有效。

这是我的尝试,不幸的是给出了错误的结果:

SELECT *,
    CASE
        WHEN (AB IS NOT NULL AND (AB <= B OR B IS NULL)) THEN AB
        WHEN (A IS NOT NULL AND (A <= B OR B IS NULL)) THEN B
        ELSE NULL
    END AS SupplementDate
FROM Table1
WHERE (B IS NOT NULL OR AB IS NOT NULL) 
AND (C IS NULL OR (B IS NOT NULL AND (A IS NOT NULL OR AB IS NOT NULL)))
ORDER BY ID;

数据和方法:db<>fiddle

期望的结果:

ID A AB B C SupplementDate
1 2021-01-01 2021-02-01 2021-03-01 2021-04-01 2021-02-01
2 null 2021-06-01 null 2021-08-01 2021-06-01
3 2021-09-01 null 2021-08-01 null null
4 null null 2021-11-01 null null
5 2021-09-01 2021-06-01 null null 2021-06-01
6 2021-09-01 null 2021-11-01 2021-11-02 2021-11-01
7 2021-09-01 2021-09-01 2021-11-01 2021-11-02 2021-09-01
8 2021-09-01 null 2021-09-01 2021-11-02 2021-09-01
9 2021-09-01 null 2021-09-01 2021-08-02 null
10 2021-09-01 null 2021-09-01 2021-07-02 null
11 2021-09-01 2021-09-01 null null 2021-09-01
12 2021-08-01 2021-09-01 null null 2021-09-01
13 2021-08-01 2021-09-01 null 2021-10-01 2021-09-01
14 2021-08-01 null null 2021-09-01 null
15
英文:

Data consists of IDs who take supplements (A, AB, B, C) on specified dates as follows:

ID A AB B C
1 2021-01-01 2021-02-01 2021-03-01 2021-04-01
2 null 2021-06-01 null 2021-08-01
3 2021-09-01 null 2021-08-01 null
4 null null 2021-11-01 null
5 2021-09-01 2021-06-01 null null
6 2021-09-01 null 2021-11-01 2021-11-02
7 2021-09-01 2021-09-01 2021-11-01 2021-11-02
8 2021-09-01 null 2021-09-01 2021-11-02
9 2021-09-01 null 2021-09-01 2021-08-02
10 2021-09-01 null 2021-09-01 2021-07-02
11 2021-09-01 2021-09-01 null null
12 2021-08-01 2021-09-01 null null
13 2021-08-01 2021-09-01 null 2021-10-01
14 2021-08-01 null null 2021-09-01
15 2021-09-01 2021-12-01 null 2021-09-01
16 2021-10-01 null null 2021-09-01

Supplement AB consists of supplements A and B.

I need to classify each ID and receive the date of an ID taking B or AB or both together if the following criteria apply:

  1. B or AB must be taken before C (or C IS NULL).
  2. If B is taken, A or AB needs to be taken before B or simultaneously. If AB was taken before B, AB is the date to receive. When A was taken before B, B is the date to receive.

Furthermore, sometimes an ID can receive supplements together, which is also okay. For example ID 11 with A and AB.

When I take a look at the table, it's easy to apply but putting this into a logic does not work as I expected.

This is my attempt which unfortunately gives wrong results:
Maybe there is a completely different method to do something like this?

SELECT *,
    CASE
        WHEN (AB IS NOT NULL AND (AB &lt;= B OR B IS NULL)) THEN AB
        WHEN (A IS NOT NULL AND (A &lt;= B OR B IS NULL)) THEN B
        ELSE NULL
    END AS SupplementDate
FROM Table1
WHERE (B IS NOT NULL OR AB IS NOT NULL) 
AND (C IS NULL OR (B IS NOT NULL AND (A IS NOT NULL OR AB IS NOT NULL)))
ORDER BY ID;

Data and approach: db<>fiddle

The expected result:

ID A AB B C SupplementDate
1 2021-01-01 2021-02-01 2021-03-01 2021-04-01 2021-02-01
2 null 2021-06-01 null 2021-08-01 2021-06-01
3 2021-09-01 null 2021-08-01 null null
4 null null 2021-11-01 null null
5 2021-09-01 2021-06-01 null null 2021-06-01
6 2021-09-01 null 2021-11-01 2021-11-02 2021-11-01
7 2021-09-01 2021-09-01 2021-11-01 2021-11-02 2021-09-01
8 2021-09-01 null 2021-09-01 2021-11-02 2021-09-01
9 2021-09-01 null 2021-09-01 2021-08-02 null
10 2021-09-01 null 2021-09-01 2021-07-02 null
11 2021-09-01 2021-09-01 null null 2021-09-01
12 2021-08-01 2021-09-01 null null 2021-09-01
13 2021-08-01 2021-09-01 null 2021-10-01 2021-09-01
14 2021-08-01 null null 2021-09-01 null
15 2021-09-01 2021-12-01 null 2021-09-01 null
16 2021-10-01 null null 2021-09-01 null

答案1

得分: 1

您的条件并不是100清晰但看起来您可以这样做
```tsql
SELECT *
    CASE
        WHEN (LEAST(ABB) &lt;= C OR C IS NULL)
            AND (LEAST(ABA) &lt;= B OR B IS NULL)
        THEN LEAST(ABB)
    END AS 补充日期
FROM 表1
ORDER BY ID;

在较旧版本的SQL Server中,您不能使用LEAST。因此,您需要使用大量的CASEIIF

SELECT *
    CASE
        WHEN (IIF(AB IS NOT NULLIIF(B IS NOT NULL AND B &lt; ABBAB)B) &lt;= C OR C IS NULL)
            AND (IIF(AB IS NOT NULLIIF(A IS NOT NULL AND A &lt; ABAAB)A) &lt;= B OR B IS NULL)
        THEN IIF(AB IS NOT NULLIIF(B IS NOT NULL AND B &lt; ABBAB)B)
    END AS 补充日期
FROM 表1
ORDER BY ID;

db<>fiddle


<details>
<summary>英文:</summary>

Your conditions aren&#39;t 100% clear, but it looks like you can do it like this
```tsql
SELECT *,
    CASE
      WHEN (LEAST(AB, B) &lt;= C OR C IS NULL)
       AND (LEAST(AB, A) &lt;= B OR B IS NULL)
      THEN LEAST(AB, B)
    END AS SupplementDate
FROM table1
ORDER BY ID;

In older versions of SQL Server, you can't use LEAST. So you need to do a bunch of CASE or IIF

SELECT *,
    CASE
      WHEN (IIF(AB IS NOT NULL, IIF(B IS NOT NULL AND B &lt; AB, B, AB), B) &lt;= C OR C IS NULL)
       AND (IIF(AB IS NOT NULL, IIF(A IS NOT NULL AND A &lt; AB, A, AB), A) &lt;= B OR B IS NULL)
      THEN IIF(AB IS NOT NULL, IIF(B IS NOT NULL AND B &lt; AB, B, AB), B)
    END AS SupplementDate
FROM table1
ORDER BY ID;

db<>fiddle

huangapple
  • 本文由 发表于 2023年7月13日 20:18:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679301.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定