我曾经拥有以下代码,以便获得所有' - '对所有客户的行动:
with
T1 as
(
select
[Contract] = 'Contract1',
[Customer] = 'Customer4',
[Date] = '2017-01-01',
[Action] = '+'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer6',
[Date] = '2017-01-02',
[Action] = '+'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer4',
[Date] = '2017-01-03',
[Action] = '-'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer4',
[Date] = '2017-01-04',
[Action] = '+'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer4',
[Date] = '2017-01-05',
[Action] = '-'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer6',
[Date] = '2017-01-06',
[Action] = '-'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer8',
[Date] = '2017-01-07',
[Action] = '+'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer8',
[Date] = '2017-01-08',
[Action] = '-'
union all
select
[Contract] = 'Contract1',
[Customer] = 'Customer4',
[Date] = '2017-01-09',
[Action] = '+'
)
select
[Customer],
[Date]
from T1
where [Action] = '-'
现在我需要通过合同字段来完成。这意味着我必须在最后一次操作时返回合同和日期值 - ' - '所有客户都使用' +'在该日期之前的行动。非常期望的输出应该是:
Date | Contract
------------ | ------
2017-01-06 | Contract1
2017-01-08 | Contract1
预期算法应如下所示:
[PlusDC] = count(distinct iif([Action] = '+',Customer,NULL)) over (partition by [Contract] order by [Date])
[MinusDC] = count(distinct iif([Action] = '-',Customer,NULL)) over (partition by [Contract] order by [Date])
可是:
粗略地说,我必须针对所有客户检查以下代码:
[动作] =' - '对于当前行。
滞后([行动],1)=' - ' (或如果客户记录在当天晚些时候出现,则为每个客户。)
更新:为了使事情更加清晰,我已经以列为导向查看了我的数据:
-----------------------------------------------------------------------
| Date | Contract | Customer4 | Customer6 | Customer8 | All |
| ------------ | --------- | --------- | --------- | --------- | --- |
| 2017-01-01 | Contract1 | + | | | |
| 2017-01-02 | Contract1 | | + | | |
| 2017-01-03 | Contract1 | | | | |
| 2017-01-04 | Contract1 | - | | | | <-- Customer6 still has a '+'
| 2017-01-05 | Contract1 | + | | | |
| 2017-01-06 | Contract1 | - | | | | <-- Customer6 still has a '+'
| 2017-01-07 | Contract1 | | - | | - | <-- All customers has '-' or null as a last action
| 2017-01-08 | Contract1 | | | + | |
| 2017-01-09 | Contract1 | | | - | - | <-- All customers has '-' or null as a last action
-----------------------------------------------------------------------
All列表示所有客户的实际状态(我需要的行)。您可能会注意到2017-01-04和2017-01-06并不是真实的 - &#39; - &#39;在合同字段内。 Contract1尚未关闭,它仍然打开了Customer6。如果每份合同都有一定数量的客户,那就很容易了。无数呢?
有任何实际建议吗?
答案 0 :(得分:1)
我认为你可以像这样使用ROW_NUMBER()
:
;with tt as (
select T1.[Contract], T1.[Date], T1.[Action], t.[Customer], t.[Action] lAction, t.[Date] lDate
-- this `rn` will give me the last action for each other customer older that each Date
, row_number() over (partition by T1.[Contract], T1.[Date], t.[Customer] order by t.[Date] desc) rn
from T1
-- I use this self left join to gather data with:
left join T1 t
on T1.[Contract] = t.[Contract] -- same Contract
and T1.[Date] > t.[Date] -- older than current date
and T1.[Customer] != t.[Customer] -- for other customers
-- So I will have actions of other customer older than each date
)
select [Contract], [Date]
from T1
-- I just check if there is not any data in `tt` with:
where not exists(
select 1
from tt
where tt.[Contract] = T1.[Contract] -- same contract
and tt.[Date] = T1.[Date] -- same date
and rn = 1 -- only last action
and (T1.[Action] = '+' -- current customer's action is '+'
or isnull(lAction, '+') = '+') -- or others last actions is '+'
)
group by [Contract], [Date];
答案 1 :(得分:1)
好的我要先填写一张像你一样的表来解决这个问题。我要做的是重复每个日期的客户和合同的每个组合。
我将此CTE附加到您的示例代码:
,
FullTable as
(
select
a.[Contract]
,a.[Customer]
,b.[Date]
,c.[Action]
,count(c.[Action]) over (partition by a.[Contract],a.[Customer] order by b.[Date]) c
from
(select distinct
[Contract],
[Customer]
from T1) a
inner join
(select distinct
[Contract],
[Date]
from T1) b
on a.[Contract]=b.[Contract]
left join t1 c
on c.[Contract]=a.[Contract] and a.[Customer]=c.[Customer] and b.[Date]=c.[Date]
)
现在Fulltable做了两件事,它确保每个客户每天都有一行。如果源数据中没有该客户的操作,则Action为NULL。 我做的第二件事是使用窗口计数
计算先前操作的数量count(c.[Action]) over (partition by a.[Contract],a.[Customer] order by b.[Date]) c
计数不计算NULL值,因此这实际上对数据进行分组,每个客户的一个组对于每个日期都有一个值,并且任何直接来自NULL操作的行都会获得相同的组
以下是客户4的数据
Contract Customer Date c Action
Contract1 Customer4 2017-01-01 1 +
Contract1 Customer4 2017-01-02 1 NULL
Contract1 Customer4 2017-01-03 2 -
Contract1 Customer4 2017-01-04 3 +
Contract1 Customer4 2017-01-05 4 -
Contract1 Customer4 2017-01-06 4 NULL
Contract1 Customer4 2017-01-07 4 NULL
Contract1 Customer4 2017-01-08 4 NULL
Contract1 Customer4 2017-01-09 5 +
现在我创建了一个名为DaillyStatus的新CTE。此CTE填写NULLS,因此现在每天都保留该合同和客户的最新状态而不是NULL。这意味着对于表中的每一天,可以找到每个客户合同组合的状态。要做到这一点,我只需为刚刚找到的每个组获取MAX
,DailyStatus as
(
select
[Contract]
,[Customer]
,[Date]
,[Action]
,c
,max([Action]) over (partition by [Contract],[Customer],c) FilledAction
from
FullTable
)
Contract Customer Date c FilledAction Action
Contract1 Customer6 2017-01-01 0 NULL NULL
Contract1 Customer6 2017-01-02 1 + +
Contract1 Customer6 2017-01-03 1 + NULL
Contract1 Customer6 2017-01-04 1 + NULL
Contract1 Customer6 2017-01-05 1 + NULL
Contract1 Customer6 2017-01-06 2 - -
Contract1 Customer6 2017-01-07 2 - NULL
Contract1 Customer6 2017-01-08 2 - NULL
Contract1 Customer6 2017-01-09 2 - NULL
使用此表,我们可以获取表中每个日期的每个客户的状态。自'+'&gt;' - '&gt; NULL我们可以找到所有客户都有' - '的日期,因为最新的动作在该日期或之前没有动作(NULL)
select
[Contract]
,[Date]
,max(FilledAction)
from DailyStatus
group by [Contract],[Date]
having max(FilledAction) ='-'
完整的解决方案在这里:
,FullTable as
(
select
a.[Contract]
,a.[Customer]
,b.[Date]
,c.[Action]
,count(c.[Action]) over (partition by a.[Contract],a.[Customer] order by b.[Date]) c
from
(select distinct
[Contract],
[Customer]
from T1) a
inner join
(select distinct
[Contract],
[Date]
from T1) b
on a.[Contract]=b.[Contract]
left join t1 c
on c.[Contract]=a.[Contract] and a.[Customer]=c.[Customer] and b.[Date]=c.[Date]
)
,DailyStatus as
(
select
[Contract]
,[Customer]
,[Date]
,[Action]
,c
,max([Action]) over (partition by [Contract],[Customer],c) FilledAction
from
FullTable
)
select
[Contract]
,[Date]
,max(FilledAction)
from DailyStatus
group by [Contract],[Date]
having max(FilledAction) ='-'
答案 2 :(得分:0)
感谢答案,我提出了自己的解决方案,这个解决方案和Søren一样正确,并且和shA.t的解决方案一样快。多谢你们!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
// DO NITHING
} else {
// DO WHATEVER YOU WANT TO DO WITH THE CELLS IN YOUR OTHER SECTIONS
}
}