如何按一列在table组中创建子table?
How to create sub-table in tables group by one column?
我一直在做SQL,卡在一个点上。
例如,假设我们有一个 Table 员工,其列为 Emp_ID(varchar)、DELIVERY_TIME(date)、Delivery_number(Varchar)
EMP_ID
DELIVERY_TIME
DELIVERY_NUMBER
E01
21-08-2021
4
E01
21-08-2019
1
E01
21-08-2022
5
E01
21-05-2021
2
E01
07-08-2021
3
E02
21-08-2021
4
E02
21-08-2023
5
E02
21-08-2020
1
E02
21-06-2021
2
E02
06-08-2021
3
现在我想通过一些查询在其中添加一个状态列来操作 table,例如:
EMP_ID
DELIVERY_TIME
STATUS
E01
21-08-2021
IN FUTURE
E01
21-08-2019
DELIVERED
E01
21-08-2022
IN FUTURE
E01
21-05-2021
DELIVERED
E01
07-08-2021
DELIVERING
E02
26-08-2021
IN FUTURE
E02
21-08-2023
IN FUTURE
E02
21-08-2020
DELIVERED
E02
21-06-2021
DELIVERED
E02
06-08-2021
DELIVERING
基本上,如果今天是 2021 年 9 月 8 日 (08-08-2021),那么,
- 对于日期 > ,在 - 未来
- 日期 < ,送达
- 对于 max(date) < ,交付。
- 从所有小于当前日期的日期中,最大(最新)个应标记为已交付。 (只有一个会在那里)。例如,如果今天的日期是 08-08-2021,而在数据库中我们有诸如 07-08-2021、06-08-2021 和 05-08-2021 之类的日期,那么 07-08-2021 应该被标记为交付,但是其余两个应标记为已交付。
但这是针对每个员工 ID 分别完成的。
此外,如果这可以仅使用查询而不使用脚本来完成,那将更可取。我们还可以添加新的 EMP_IDs.
请指导。
谢谢。
您需要一个带有日期比较的 case
表达式。我认为是这样的逻辑:
select e.*,
(case when curdate() <= delivery_time then 'In future'
when curdate() = delivery_time - interval 1 day then 'Delivering'
else 'Delivered'
end) as status
from employee e;
如果 delivery_time
有时间成分,那么你需要在逻辑中 date(deliery_time)
。
备注:
- 我希望名为
employee
的 table 每个员工一行,其中 emp_id
作为主键。
- 我希望名为
delivery_time
的列具有时间分量,但您的示例数据表明它没有。
您可以为此使用 SQL CASE:https://sql.sh/cours/case
SELECT *, CASE
WHEN DELIVERY_TIME < NOW() THEN 'DELIVERED'
WHEN DELIVERY_TIME > NOW() THEN 'IN_FUTURE'
END
FROM "Users"
但是我不知道你说的是什么意思
for max(date) < , delivering.
- 我从状态不是未来的日期中选择最大值
- 然后比较我们是否有一个 delivery_time,即等于以上点的最大日期。如果是,那么它正在交付。
with data as (
select
*,
case when when curdate() < delivery_time then 'In future'
when curdate() > delivery_time then 'delivered'
else 'not categorized'
END as status
from [table name]
),
max_date as (
select
*,
max(case when status not in ('In future') then delivery_time else null end)
over(partition by emp_id order by delivery_time desc) as max_delivery_time_when_not_in_future
from data
)
select
emp_id,
delivery_time,
case
when max_delivery_time_when_not_in_future = delivery_time
then 'delivering' else status end as final_status
from max_date
我一直在做SQL,卡在一个点上。 例如,假设我们有一个 Table 员工,其列为 Emp_ID(varchar)、DELIVERY_TIME(date)、Delivery_number(Varchar)
EMP_ID | DELIVERY_TIME | DELIVERY_NUMBER |
---|---|---|
E01 | 21-08-2021 | 4 |
E01 | 21-08-2019 | 1 |
E01 | 21-08-2022 | 5 |
E01 | 21-05-2021 | 2 |
E01 | 07-08-2021 | 3 |
E02 | 21-08-2021 | 4 |
E02 | 21-08-2023 | 5 |
E02 | 21-08-2020 | 1 |
E02 | 21-06-2021 | 2 |
E02 | 06-08-2021 | 3 |
现在我想通过一些查询在其中添加一个状态列来操作 table,例如:
EMP_ID | DELIVERY_TIME | STATUS |
---|---|---|
E01 | 21-08-2021 | IN FUTURE |
E01 | 21-08-2019 | DELIVERED |
E01 | 21-08-2022 | IN FUTURE |
E01 | 21-05-2021 | DELIVERED |
E01 | 07-08-2021 | DELIVERING |
E02 | 26-08-2021 | IN FUTURE |
E02 | 21-08-2023 | IN FUTURE |
E02 | 21-08-2020 | DELIVERED |
E02 | 21-06-2021 | DELIVERED |
E02 | 06-08-2021 | DELIVERING |
基本上,如果今天是 2021 年 9 月 8 日 (08-08-2021),那么,
- 对于日期 > ,在 - 未来
- 日期 < ,送达
- 对于 max(date) < ,交付。
- 从所有小于当前日期的日期中,最大(最新)个应标记为已交付。 (只有一个会在那里)。例如,如果今天的日期是 08-08-2021,而在数据库中我们有诸如 07-08-2021、06-08-2021 和 05-08-2021 之类的日期,那么 07-08-2021 应该被标记为交付,但是其余两个应标记为已交付。
但这是针对每个员工 ID 分别完成的。 此外,如果这可以仅使用查询而不使用脚本来完成,那将更可取。我们还可以添加新的 EMP_IDs.
请指导。 谢谢。
您需要一个带有日期比较的 case
表达式。我认为是这样的逻辑:
select e.*,
(case when curdate() <= delivery_time then 'In future'
when curdate() = delivery_time - interval 1 day then 'Delivering'
else 'Delivered'
end) as status
from employee e;
如果 delivery_time
有时间成分,那么你需要在逻辑中 date(deliery_time)
。
备注:
- 我希望名为
employee
的 table 每个员工一行,其中emp_id
作为主键。 - 我希望名为
delivery_time
的列具有时间分量,但您的示例数据表明它没有。
您可以为此使用 SQL CASE:https://sql.sh/cours/case
SELECT *, CASE
WHEN DELIVERY_TIME < NOW() THEN 'DELIVERED'
WHEN DELIVERY_TIME > NOW() THEN 'IN_FUTURE'
END
FROM "Users"
但是我不知道你说的是什么意思
for max(date) < , delivering.
- 我从状态不是未来的日期中选择最大值
- 然后比较我们是否有一个 delivery_time,即等于以上点的最大日期。如果是,那么它正在交付。
with data as (
select
*,
case when when curdate() < delivery_time then 'In future'
when curdate() > delivery_time then 'delivered'
else 'not categorized'
END as status
from [table name]
),
max_date as (
select
*,
max(case when status not in ('In future') then delivery_time else null end)
over(partition by emp_id order by delivery_time desc) as max_delivery_time_when_not_in_future
from data
)
select
emp_id,
delivery_time,
case
when max_delivery_time_when_not_in_future = delivery_time
then 'delivering' else status end as final_status
from max_date