英文:
Logic of assigning a group based on different criteria with dates
问题
以下是翻译好的部分:
数据包括在指定日期服用补充剂(A
、AB
、B
、C
)的 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
包括补充剂 A
和 B
。
我需要对每个 ID
进行分类,并在满足以下条件时获取 ID
服用 B
或 AB
或两者一起的日期:
- 必须在服用
C
(或C IS NULL
)之前服用B
或AB
。 - 如果服用
B
,则需要在服用B
之前或同时服用A
或AB
。如果在服用B
之前服用了AB
,则日期为AB
的服用日期。当在服用B
之前服用了A
时,日期为B
的服用日期。
此外,有时一个 ID
可以同时服用多种补充剂,这也是可以的。例如 ID
11 同时服用 A
和 AB
。
当我查看表格时,很容易应用,但将其转化为逻辑形式不像我预期的那样有效。
这是我的尝试,不幸的是给出了错误的结果:
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 ID
s 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:
B
orAB
must be taken beforeC
(orC
IS NULL
).- If
B
is taken,A
orAB
needs to be taken beforeB
or simultaneously. IfAB
was taken beforeB
,AB
is the date to receive. WhenA
was taken beforeB
,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 <= 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;
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(AB,B) <= C OR C IS NULL)
AND (LEAST(AB,A) <= B OR B IS NULL)
THEN LEAST(AB,B)
END AS 补充日期
FROM 表1
ORDER BY ID;
在较旧版本的SQL Server中,您不能使用LEAST
。因此,您需要使用大量的CASE
或IIF
SELECT *,
CASE
WHEN (IIF(AB IS NOT NULL,IIF(B IS NOT NULL AND B < AB,B,AB),B) <= C OR C IS NULL)
AND (IIF(AB IS NOT NULL,IIF(A IS NOT NULL AND A < AB,A,AB),A) <= B OR B IS NULL)
THEN IIF(AB IS NOT NULL,IIF(B IS NOT NULL AND B < AB,B,AB),B)
END AS 补充日期
FROM 表1
ORDER BY ID;
<details>
<summary>英文:</summary>
Your conditions aren't 100% clear, but it looks like you can do it like this
```tsql
SELECT *,
CASE
WHEN (LEAST(AB, B) <= C OR C IS NULL)
AND (LEAST(AB, A) <= 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 < AB, B, AB), B) <= C OR C IS NULL)
AND (IIF(AB IS NOT NULL, IIF(A IS NOT NULL AND A < AB, A, AB), A) <= B OR B IS NULL)
THEN IIF(AB IS NOT NULL, IIF(B IS NOT NULL AND B < AB, B, AB), B)
END AS SupplementDate
FROM table1
ORDER BY ID;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论