如何正确编写此SQL查询?

时间:2017-01-10 18:34:25

标签: mysql sql

我正在试图弄清楚如何编写查询以获得正确的结果。

我会保持简单。首先,基础:

我有两张桌子:DEALSTASKS
一笔交易可以包含一个或多个任务,因此TASKS有一个deal_id字段。

此外,每个任务都有一个time_start字段(unix时间戳)和一个completed字段(1或0)。

确定。现在,我需要什么?在我看来,我需要在呈现的“下一个任务”列中显示所有交易。

因此,对于每笔交易,如果我有一个任务(一个或多个),它必须只显示最接近的。如果没有任务,我将发出警报。

Deal Title | Value | Next step
deal 1     | 1.000 | tomorrow at 11:00
deal 2     | 1.000 | NO TASK IN THIS DEAL
deal 3     | 1.500 | 12/03/2017 at 9:00

在这个例子中,交易1里面有3个任务,但明天最近的开始。我不希望“交易1”重复3次。 < - GROUP BY deals.id ??

为了做到这一点,目前,我在没有JOIN的情况下运行交易查询,并且我使用自定义PDO类为每一行的任务运行新查询。 但这太糟糕了!我对DEALS表的每一行都有一个新查询。

我很确定有一种方法可以编写一个查询来获得此结果。

PS:不关心文本的渲染,我只用“明天”来编写示例,next_spet是db的unix时间戳...我可以轻松使用{{1}正确格式化。

编辑: 我将在2个表中提供数据,只是为了完成示例。

moment.js

注意:时间戳与我在第一个表中写的结果不匹配。它们只是一个例子,我采用DEALS ID | TITLE | VALUE 1 | Deal 1 | 1000 2 | Deal 2 | 1000 3 | Deal 3 | 1000 TASKS ID | DEAL_ID | TITLE | TIME_START | COMPLETED 1 | 1 | Send Proposal | 1483678800 | 0 2 | 1 | Follow up | 1483441200 | 0 3 | 1 | Ask for referrals | 1484441200 | 0 4 | 2 | Send email | 1483678900 | 0 5 | 3 | Sort out meeting | 1483678900 | 0 字段的时间戳并以人类可读模式格式化,但这不是我的问题。

2 个答案:

答案 0 :(得分:1)

如果您想要下一个任务的时间,可以使用相关的子查询:

select d.*,
       (select t.time_start
        from tasks t
        where t.deal_id = d.deal_id and t.time_start > d.time_col
        order by t.time_start
        limit 1
       ) as task_time_start
from deals d;

编辑:

如果您想要未来,那么只需更改时间比较:

select d.*,
       (select t.time_start
        from tasks t
        where t.deal_id = d.deal_id and t.completed = 0 and
              t.time_start > now()
        order by t.time_start
        limit 1
       ) as task_time_start
from deals d;

答案 1 :(得分:0)

这样的事情应该这样做。

select 
    d.title as 'Deal Title',
    d.value as 'Value',
    IsNull(CONVERT(VARCHAR(50), min(t.time_start)), 'NO TASK IN THIS DEAL') as 'Next step'
from Deals d
left join Tasks t
    on t.deal_id = d.deal_id
    and t.is_completed = 0
    and t.time_start > GetDate()
group by d.deal_id, d.title, d.value

这是SQLite的等价物:

select 
    d.title as 'Deal Title',
    d.value as 'Value',
    IfNull(min(t.time_start), 'NO TASK IN THIS DEAL') as 'Next step'
from Deals d
left join Tasks t
    on t.deal_id = d.deal_id
    and t.is_completed = 0
    and t.time_start > now()  --remove this line to include past Tasks
group by d.deal_id, d.title, d.value