2017-04-18 23 views
0

假设我们有这些表,指一个任务单个客户SQL:如何根据日期取一个独特的记录(用NULL情况包括在内)

AGENDAS 
ID | DAY 
86 | 2017-04-14 
88 | 2017-04-22 

WORKS 
ID     | IDAGENDA | TIME SLOT | RESULT | DATETIMEEXECUTED | IDORDER 
IZ9`fiq|-=rRE7OKKO;P | 86 | 8-10 am | canceled | 2017-04-13 10:45 | 10 
g5wMkHa4Z?bQnFqDmXKn | 88 | 8-10 am | canceled | 2017-04-19 16:30 | 10 
n\mkLegfO>HSCJ/X:{ax | 88 | 13-15 pm |   |     | 10 

与框架做我(我不得不)使用,当我创建一个面板时,我被允许编写一个查询以获取其数据。该查询称为主查询。 我的老板想要一个总结屏幕,对于每个工作订单,我必须列出最新的议程,以及案例的结果。所以,假设我们有上述表格的情况。在这种情况下,我应该只列出ID为n\mkLegfO>HSCJ/X:{ax的任务,因为它是最近插入和保留的任务,并且仍然需要执行(客户没有取消它)。 但我不知道,因为如果如何获取这个唯一的记录,在主查询,我写:

select ... 
from ORDERS O left join AGENDAS A on ... 
    left join WORKS W1 on ... 
where W1.IDORDER = 10 and W1.DATETIMEEXECUTED = (
    select max(W2.DATETIMEEXECUTED) 
    from WORKS W2 
    where W2.IDORDER = 10 
) 

则记录

g5wMkHa4Z?bQnFqDmXKn | 88 | 8-10 am | canceled | 2017-04-19 16:30 

将返回这是不是最近。在另一方面,如果我尝试:

select ... 
from ORDERS O left join AGENDAS A on ... 
    left join WORKS W1 on ... 
where W1.IDORDER = 10 and (DATETIMEEXECUTED is null or W1.DATETIMEEXECUTED = (
    select max(W2.DATETIMEEXECUTED) 
    from WORKS W2 
    where W2.IDORDER = 10) 

然后我得到:

g5wMkHa4Z?bQnFqDmXKn | 88 | 8-10 am | canceled | 2017-04-19 16:30 | 10 
n\mkLegfO>HSCJ/X:{ax | 88 | 13-15 pm |   |     | 10 

仍然是不正确的。 我认为最大的问题是,我不能因为被现场工作人员在移动设备中创建这些记录时,PK不能是简单的整数计数器和每个设备移动作为的SQLite上WORKS表执行max(ID)聚合函数和每个操作员创建他将自己的记录与中央服务器同步之前。这就是为什么我们的框架提供了一个PK作为char(20)伪随机字符。

因为我是个白痴,我没想到创建工作的日期时间,但这个应用程序已经在生产,所以我不希望改变DB模式。 此外left join是必需的,因为对于其他人,仍然没有议程和任命可能仍然存在。

那么,到底:如果只有caneled作品我想看看最近的一次。相反,如果还有一项工作仍在进行(结果和日期时间等于null),我希望得到它。 有没有解决方案?

+0

它是sql服务器...因为我添加了 –

+0

您是否正在寻找* one * IDORDER(例如IDORDER = 10)或* multiple * IDORDER及其最新记录的最新记录? –

+0

AGENDAS表格与此有什么关系? –

回答

2

为idorder的最新记录= 10:

select top(1) * 
from works 
where idorder = 10 
    and coalesce(result, 'okay') <> 'canceled' 
order by datetimeexecuted desc; 

每idorder的最新记录:

select * 
from 
(
    select *, row_number() over (partition by idorder order by datetimeexecuted desc) as rn 
    from works 
    where coalesce(result, 'okay') <> 'canceled' 
) ranked 
where rn = 1; 

更新:每idorder最新未取消的记录,如果有,否则最新的其他记录:

select * 
from 
(
    select *, 
    row_number() over (partition by idorder order by 
     case when result = 'canceled' then 2 else 1 end, datetimeexecuted desc) as rn 
    from works 
) ranked 
where rn = 1; 
+0

Ehm,这个查询应该在服务器上运行,所以我不能使用coalesce –

+1

我不明白这一点。 'COALESCE'是标准的SQL,可在SQL Server中使用。为什么你会被允许运行查询,但只有没有'COALESCE'?这似乎没有道理。 (无论如何,'coalesce(result,'okay')<>'cancelled''也可以写成'result''''取消'或结果为空'。) –

+0

对不起。我只在SQLite中看到'COALESCE()',而在SQL Server中看到'ISNULL()'等其他例程。实现该框架的同一位人员向我解释说,合并是保留给SQLite的。抱歉。无论如何,恐怕我不允许插入一个SELECT查询作为参数到FROM但只有表。我知道这个框架是有限的...... –

0

UPDATE

正如他在很好的答案建议由和Thorsten KETTNER,我创建了一个新的标准视图,其查询是完全内SELECT *, row_number()...,我用的面板,而不是的WORKS经典表的主查询这一观点。 最后,是我的情况更准确,我必须执行以下操作:

select ... 
from ORDERS O left join AGENDAS A on ... 
       left join VIEW V on ... 
where V.rn = 1 or (V.rn is null) 

,因为如果工作/任命尚未仍然在所有插入的,他们希望看到的其他有关资料无论如何。

相关问题