如果已存在其他事件,则将当天的开始/结束日期计算为0天

时间:2017-03-23 16:27:05

标签: sql-server tsql visual-studio-2012 reporting-services

我有一个查询,其中有一个"阶段"在同一天开始和结束 - 计算为1天。但是,如果另一个"阶段"在同一天开始和结束对同一个参考。没有。和期间号,然后我想把它计算为0天。

示例:

**Ref.  Period.  Phase  StDt        EndDt**
013     3        KAA    01/01/16    01/01/16  - This is one day
013     3        TAA    02/01/16    03/01/16  - this is 2 days    
013     3        KAT    01/01/16    01/01/16  - **would like this to be counted as 0 day**
013     3        TTA    04/04/16    04/04/16  - this is one day

我希望在Ref分组的数据中进行这种独特的计算。和期间数字。这是一个棘手的问题......

由于

3 个答案:

答案 0 :(得分:0)

此表达式应适用于SSRS端:

=IIF(Fields!StartDate.Value=Fields!EndDate.Value AND Fields!Phase.Value <> LOOKUPSET(Fields!StartDate.Value &"_" & Fields!EndDate.Value,Fields!StartDate.Value & "_" & Fields!EndDate.Value,Fields!Phase.Value,"DatasetName").GetValue(0),0,DATEDIFF("D",Fields!StartDate.Value,Fields!EndDate.Value)+1)

对于数据集返回的第一个阶段,它将返回值1。如果阶段 - 日期范围组合在分组中不是唯一的,则这不会像写入的那样工作,但您应该能够相应地进行修改。

此外,如果行在SSRS和数据集之间的排序方式不同,则它可能不是第一行获得1的行。

答案 1 :(得分:0)

试试这个。 我假设您正在使用TSQl(不确定您是否也标记了SQL。

;WITH cte_result(ID,Ref, Period,Phase,StDt,EndDt) AS
(
SELECT 1,'013' ,3,'KAA',CAST('01/01/16'AS DATETIME),CAST('01/01/16'AS DATETIME) UNION ALL
SELECT 2,'013' ,3,'TAA','01/02/16','01/03/16' UNION ALL 
SELECT 3,'013' ,3,'KAT','01/01/16','01/01/16' UNION ALL
SELECT 4,'013' ,3,'TTA','04/04/16','04/04/16')
,cte_PreResult AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY CAST(StDt AS DATE), CAST(EndDt AS DATE) ORDER BY ID) AS [Order],
    Ref,
    Period,
    Phase,
    StDt,
    EndDt
FROM cte_result
)
SELECT Ref,
    Period,
    Phase,
    StDt,
    EndDt,
    CASE 
        WHEN [Order] <> 1
            THEN '0 Day(s)'
        ELSE CAST(DATEDIFF(dd, StDt, EndDt) + 1 AS VARCHAR(10)) + ' Day(s)'
        END AS Comment
FROM cte_PreResult

如果没有ID列,则选择一些要按顺序排列的列,可能是Phase,因此将Phase替换为Phase ROW_NUMBER()OVER(PARDTION BY StDt,EndDt ORDER BY ID)AS [Order] ,如果没有候选列可供选择,那么试试这个

;WITH cte_result(ID,Ref, Period,Phase,StDt,EndDt) AS
(
SELECT 1,'013' ,3,'KAA',CAST('01/01/16'AS DATETIME),CAST('01/01/16'AS DATETIME) UNION ALL
SELECT 2,'013' ,3,'TAA','01/02/16','01/03/16' UNION ALL 
SELECT 3,'013' ,3,'KAT','01/01/16','01/01/16' UNION ALL
SELECT 4,'013' ,3,'TTA','04/04/16','04/04/16')
,cte_PreResult AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY CAST(StDt AS DATE), CAST(EndDt AS DATE) ORDER BY (SELECT NULL)) AS [Order],
    Ref,
    Period,
    Phase,
    StDt,
    EndDt
FROM cte_result
)
SELECT Ref,
    Period,
    Phase,
    StDt,
    EndDt,
    CASE 
        WHEN [Order] <> 1
            THEN '0 Day(s)'
        ELSE CAST(DATEDIFF(dd, StDt, EndDt) + 1 AS VARCHAR(10)) + ' Day(s)'
        END AS Comment
FROM cte_PreResult

答案 2 :(得分:0)

以下就是诀窍!基本上,我使用count聚合来计算阶段在同一天PER Ref和period开始和结束的实例数。然后,对于任何超过1的地方,我只使用简单的大小写语句将第一个计为1,将后续的任何一个计为0.我将以下作为子连接中的子查询创建为左外连接: / p>

LEFT OUTER JOIN
                      (SELECT     TOP (100) PERCENT Period, Ref, 
CONVERT(date, PhaseStartDate) AS stdt, CONVERT(date, PhaseEndDate) AS enddt, 
COUNT(*) 
                                               AS NoOfSameDayPhases, 
MIN(PhaseSequence) AS FirstPhSeq
                        FROM          Phases AS Phases_1
                        WHERE      (CONVERT(date, PhaseStartDate) = 
CONVERT(date, PhaseEndDate))
                        GROUP BY VoidPeriod, Ref, CONVERT(date, 
PhaseStartDate), CONVERT(date, PhaseEndDate)) AS SameDayPH ON CONVERT(date, 
                  PhaseEndDate) = SameDayPH.enddt AND CONVERT(date, 
PhaseStartDate) = SameDayPH.stdt AND 
                  VoidPeriod = SameDayPH.VoidPeriod AND SameDayPH.Ref = 
VoidPhases.Ref