SQL - 根据另一个表中的日期识别记录的状态 (postgresql)

问题描述 投票:0回答:3

我有下表

worker_log

日志日期 total_workers 商店
2021-01-01 2 拉尔夫斯
2021-02-01 0 拉尔夫斯
2021-03-01 3 拉尔夫斯
2021-01-01 3 本尼的
2021-02-01 0 本尼的
2021-03-01 1 本尼的

添加有关如何阅读上表的其他上下文:

对于 Ralphs,从 1/1/21 到 1/31/21,总共有 2 个工人。从 2/1 到 2/28/21,共有 0 个工人。所以在 2/1/21,worker 数量从 2 变为 0。从 3/1/21 到现在,共有 3 个 worker。所以在 21 年 3 月 1 日,工人数量从 0 变为 3。

我有以下名为

request_log
的临时表:

ticket_no 请求日期 商店
10000 2021-01-03 拉尔夫斯
10001 2021-01-08 拉尔夫斯
10002 2021-02-05 拉尔夫斯
10003 2021-04-03 拉尔夫斯
10004 2021-01-21 本尼的
10005 2021-02-23 本尼的
10006 2021-04-03 本尼的

我需要创建另一个表,称为

requests
,它显示是否在特定日期请求了请求票,是否有基于
log_date
worker_log
表的工作人员。
requests
表的最终结果应该是这样的:

ticket_no 请求日期 商店 workers_available
10000 2021-01-03 拉尔夫斯 真实
10001 2021-01-08 拉尔夫斯 真实
10002 2021-02-05 拉尔夫斯
10003 2021-04-03 拉尔夫斯 真实
10004 2021-01-21 本尼的 真实
10005 2021-02-23 本尼的
10006 2021-04-03 本尼的 真实

我将如何使用 SQL 脚本来解决这个问题?我正在使用 postgresql。我对 LATERAL 连接做了一些研究,但我不太确定如何实现它。

非常感谢提前提供的任何帮助!

sql database postgresql rdbms
3个回答
0
投票

要解决这个问题,需要:

  1. 使用 INNER JOIN 比较两个表之间的公共标识符,在本例中为 request_date 和 log_date

  2. 使用 CASE 表达式创建一个新的

    workers_available
    列,如果 total_workers 变量大于 0,则设置为 True,否则设置为 false。

因此,这可以通过以下方式完成:

select t1.ticket_no, t1.request_date, t1.store, case when t2.total_workers>0 then 'true' else 'false' end as workers_available from request_log as t1 inner join worker_log as t2 on t1.request_date=t2.log_date;

为了测试这个查询,我从上面的表中创建了两行假设数据 - 一行的 total_workers 大于 0,另一行不是。

select * from request_log;
 ticket_no |    request_date     | store  
-----------+---------------------+--------
     10000 | 2021-01-03 00:00:00 | Ralphs
     10001 | 2021-01-08 00:00:00 | Ralphs
(2 rows)

select * from worker_log;
      log_date       | total_workers | store  
---------------------+---------------+--------
 2021-01-03 00:00:00 |             2 | Ralphs
 2021-01-08 00:00:00 |             0 | Ralphs
(2 rows)

运行上述查询后,我们可以看到 total_workers=2 的条目为 True,而 total_workers=0 的条目为 False。

select t1.ticket_no, t1.request_date, t1.store, case when t2.total_workers>0 then 'true' else 'false' end as workers_available from request_log as t1 inner join worker_log as t2 on t1.request_date=t2.log_date;
 ticket_no |    request_date     | store  | workers_available 
-----------+---------------------+--------+-------------------
     10000 | 2021-01-03 00:00:00 | Ralphs | true
     10001 | 2021-01-08 00:00:00 | Ralphs | false
(2 rows)

请注意,您可能还会发现有关 case 表达式 的教程很有帮助。


0
投票

您可以像这样通过各自的日期和商店加入2张桌子:

select
      r.ticket_no   
    , r.request_date    
    , r.store   
    , case when w.total_workers > 0 then 'true' else 'false' end as workers_available
from request_log as r
inner join worker_log as w on r.request_date = w.log_date 
                          and r.store = w.store

但是有一些重要的假设。日期与显示的完全一致,并且不包含可变时间元素,例如2021-01-03 13:24:35 并且两个表中商店名称的拼写完全相同。

此外,不知道 worker_log 表中的每个商店是否代表每个日期,如果该表可能会跳过 request_log 中找到的任何日期,那么您可能需要一个

left join
而不是像这样:

select
      r.ticket_no   
    , r.request_date    
    , r.store   
    , case when coalesce(w.total_workers,0) > 0 then 'true' else 'false' end as workers_available
from request_log as r
left join worker_log as w on r.request_date = w.log_date
                          and r.store = w.store

如果任何时间戳列确实包含可变时间元素,那么您可以在连接逻辑中使用

date_trunc()
,但这可能会对性能产生负面影响。例如

left join worker_log as w on date_trunc('day',r.request_date) = w.log_date
                          and r.store = w.store

0
投票

我还没有看到你的尝试,但试试这个:

select 
r.ticket_no,
r.request_date,
r.store,
case 
when w.total_workers = 0 then 'false'
when w.total_workers > 0 then 'true'
else 'N/A' end as workers_available
from request_log r
left join 
worker_log w
on 
r.request_date=w.log_date
© www.soinside.com 2019 - 2024. All rights reserved.