每个日期都有多个日期字段的SQL COUNT

时间:2018-12-18 07:58:19

标签: sql sql-server datetime sql-server-2012 sql-server-2014

我有下表和没有给出正确结果的查询。

JOB表具有打开,结束和关闭日期。

现在,我需要按每个日期和位置拉动所选日期组之间的未完成,已完成和已关闭作业的数量。

请帮助我获得低于预期结果的结果

+-------+-----------+------------+-----------+----------+
| JOB_id| DateOpen  | DateFinish | DateClose | Location |
+-------+-----------+------------+-----------+----------+
|   100 | 16-Dec-18 | 18-Dec-18  | 19-Dec-18 | A        |
|   101 | 16-Dec-18 | 18-Dec-18  | 19-Dec-18 | A        |
|   102 | 17-Dec-18 | 19-Dec-18  | 20-Dec-18 | C        |
|   103 | 10-Dec-18 | 11-Dec-18  | 16-Dec-18 | D        |
|   104 | 17-Dec-18 | 19-Dec-18  | 18-Dec-18 | E        |
+-------+-----------+------------+-----------+----------+

查询:

SELECT count(DateOpen) as Opened,
       count(DateFinish) as Finised,
      count(DateClose) as Closed,
      (DateOpen) as Date 
FROM JOBS
WHERE DateOpen BETWEEN '12/16/2018' AND DATEADD(DAY, 1, '12/17/2018')
group by DateOpen

预期结果:

+-----------+------+----------+--------+----------+
|   Date    | Open | Finished | Closed | Location |
+-----------+------+----------+--------+----------+
| 16-Dec-18 |    2 |        0 |      0 | A        |
| 16-Dec-18 |    0 |        0 |      1 | D        |
| 17-Dec-18 |    1 |        0 |      0 | C        |
| 17-Dec-18 |    1 |        0 |      0 | E        |
+-----------+------+----------+--------+----------+

9 个答案:

答案 0 :(得分:1)

您可以将所有开放日期,结束日期和结束日期放在一列中,并使其与工作表一起加入:

DECLARE @date1 AS DATE = '2018-12-16';
DECLARE @date2 AS DATE = '2018-12-17';

WITH dates(date) AS (
    SELECT DateOpen FROM jobs
    UNION
    SELECT DateFinish FROM jobs
    UNION
    SELECT DateClose FROM jobs
)
SELECT dates.date
     , Location
     , COUNT(CASE WHEN dates.date = DateOpen THEN 1 END) AS Opened
     , COUNT(CASE WHEN dates.date = DateFinish THEN 1 END) AS Finished
     , COUNT(CASE WHEN dates.date = DateClose THEN 1 END) AS Closed
FROM dates
LEFT JOIN jobs ON dates.date IN (DateOpen, DateFinish, DateClose)
WHERE dates.date BETWEEN @date1 AND @date2
GROUP BY dates.date
       , Location

结果:

| date       | Location | Opened | Finished | Closed |
|------------|----------|--------|----------|--------|
| 16/12/2018 | A        | 2      | 0        | 0      |
| 16/12/2018 | D        | 0      | 0        | 1      |
| 17/12/2018 | C        | 1      | 0        | 0      |
| 17/12/2018 | E        | 1      | 0        | 0      |

Demo on DB Fiddle

答案 1 :(得分:0)

您可以在下面的查询中使用所需的结果集。

tf.train.Saver()

答案 2 :(得分:0)

首先,我建议您停止将日期存储为文本,并使用适当的数据类型。

要执行所需的操作,请选择每个日期列和位置,并将所有日期和位置合并为一个结果(第一个cte-allDates),以列出所有日期和位置。然后,我们需要一个不同的列表(第二个cte-聚合的)进行选择,并计算表中与当前日期/位置值匹配的行数。

这是整个解决方案:

.humanize()

答案 3 :(得分:0)

您可以将case语句与sum一起使用

    SELECT  Convert(date,DateOpen) as Date ,      
           sum(case when DateOpen =DateOpen then 1 else 0 end) as Opened,
           sum(case when DateFinish=DateOpen then 1 else 0 end) as Finised,
           sum(case when DateClose=DateOpen then 1 else 0 end) as Closed,
           Location

    FROM JOBS
    WHERE DateOpen BETWEEN '12/16/2018' AND DATEADD(DAY, 1, '12/17/2018')
    group by Convert(date,DateOpen),Location

    UNION

    SELECT  Convert(date,DateClose) as Date ,      
           sum(case when DateOpen =DateClose then 1 else 0 end) as Opened,
           sum(case when DateFinish=DateClose then 1 else 0 end) as Finised,
           sum(case when DateClose=DateClose then 1 else 0 end) as Closed,
           Location

    FROM JOBS
    WHERE DateClose BETWEEN '12/16/2018' AND DATEADD(DAY, 1, '12/16/2018')
    group by Convert(date,DateClose),Location

答案 4 :(得分:0)

您可以使用SUM函数尝试以下代码,该函数求和输入日期的进程状态:

SELECT Convert(date1,DateOpen) as Date,
       sum(case
            when DateOpen = Convert(date1,DateOpen) then 1
            else 0
           end) as Open,
       sum(case
            when DateFinish = Convert(date1,DateOpen) then 1
            else 0
           end) as Finished,
      sum(case
            when DateClose = Convert(date1,DateOpen) then 1
            else 0
           end) as Closed,
      Location
FROM JOBS
group by Location
UNION ALL  
SELECT Convert(date2,DateOpen) as Date,
       sum(case
            when DateOpen = Convert(date2,DateOpen) then 1
            else 0
           end) as Open,
       sum(case
            when DateFinish = Convert(date2,DateOpen) then 1
            else 0
           end) as Finished,
      sum(case
            when DateClose = Convert(date2,DateOpen) then 1
            else 0
           end) as Closed,
      Location
FROM JOBS
group by Location;
  

已编辑:date1date2是输入参数。

答案 5 :(得分:0)

DECLARE @startDate DATETIME = '12/16/2018'
DECLARE @endDate DATETIME = '12/17/2018'

SELECT 
  count(CASE when DateOpen BETWEEN @startDate AND @endDate THEN 1 end) as Opened,
  count(CASE when DateFinish BETWEEN @startDate AND @endDate THEN 1 end) as Finised,
  count(CASE when DateClose BETWEEN @startDate AND @endDate THEN 1 end) as Closed,
  DateOpen as Date,
  Location
FROM JOBS
WHERE DateOpen BETWEEN @startDate AND @endDate
group by DateOpen, Location

答案 6 :(得分:0)

您可以尝试使用unpivot来查看效果如何

with cols_to_rows
  as (
      select *
        from t
      unpivot(col for val in (dateopen,datefinish,dateclose))m 
      )
select col
       ,location 
       ,count(case when val='dateopen' then 1 end)   as open1
       ,count(case when val='datefinish' then 1 end) as finish
       ,count(case when val='dateclose' then 1 end)  as close1
  from cols_to_rows
where col between cast('2018-12-16' as date)
  and cast('2018-12-17' as date)
group by col,location,val
order by col,location


| 10/12/2018 00:00:00 | D | 1 | 0 | 0 |
| 11/12/2018 00:00:00 | D | 0 | 1 | 0 |
| 16/12/2018 00:00:00 | A | 2 | 0 | 0 |
| 16/12/2018 00:00:00 | D | 0 | 0 | 1 |
| 17/12/2018 00:00:00 | C | 1 | 0 | 0 |
| 17/12/2018 00:00:00 | E | 1 | 0 | 0 |
| 18/12/2018 00:00:00 | A | 0 | 2 | 0 |
| 18/12/2018 00:00:00 | E | 0 | 0 | 1 |
| 19/12/2018 00:00:00 | A | 0 | 0 | 2 |
| 19/12/2018 00:00:00 | C | 0 | 1 | 0 |
| 19/12/2018 00:00:00 | E | 0 | 1 | 0 |
| 20/12/2018 00:00:00 | C | 0 | 0 | 1 |

这是dbfiddle链接

https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=1ca0c0180a4d31d6e112e9f3b1b99715

答案 7 :(得分:0)

尝试一下:

    DECLARE @MinDate DATE = '12/16/2018',
            @MaxDate DATE = '12/17/2018'


    DECLARE @DateTable TABLE (DateOpen DATETIME)

    INSERT INTO @DateTable
    SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
            Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
    FROM    sys.all_objects a
            CROSS JOIN sys.all_objects b;

    ;with cte
    As
    (
        SELECT DISTINCT d.DateOpen, 
        SUM(CASE WHEN j.DateOpen =d.DateOpen THEN 1 ELSE 0 END) OVER(partition by d.DateOpen,Location) As [Open]
        ,SUM(CASE WHEN j.DateFinish =d.DateOpen THEN 1 ELSE 0 END) OVER(partition by d.DateOpen,Location) As [Finished]
        ,SUM(CASE WHEN j.DateClose =d.DateOpen THEN 1 ELSE 0 END) OVER(partition by d.DateOpen,Location) As [Closed]
        ,Location
        FROM @DateTable d
        CROSS JOIN JOBS j   
    )

    Select * from cte where [Open]>0 or Finished>0 or Closed>0
    Order by DateOpen,Location

答案 8 :(得分:0)

尝试这个

WITH CTE AS
(
SELECT *
FROM
(
SELECT Location
FROM T
GROUP BY Location
) L CROSS APPLY
(
  SELECT DateOpen
  FROM T
  WHERE DateOpen BETWEEN '2018-12-16' AND '2018-12-18'
) D
GROUP BY Location, DateOpen
),
 F AS
(
SELECT *,
       (SELECT COUNT(1) FROM T WHERE Location = CTE.Location AND DateOpen = CTE.DateOpen) [Open],
       (SELECT COUNT(1) FROM T WHERE Location = CTE.Location AND DateFinish = CTE.DateOpen)[Finish],
       (SELECT COUNT(1) FROM T WHERE Location = CTE.Location AND DateClose = CTE.DateOpen) [Close]
FROM CTE
)
SELECT DateOpen,
       [Open],
       [Finish],
       [Close],
       Location
FROM F
WHERE [Open] > 0
      OR
      [Finish] > 0
      OR
      [Close] > 0
ORDER BY DateOpen

返回:

+---------------------+------+--------+-------+----------+
|      DateOpen       | Open | Finish | Close | Location |
+---------------------+------+--------+-------+----------+
| 16/12/2018 00:00:00 |    2 |      0 |     0 | A        |
| 16/12/2018 00:00:00 |    0 |      0 |     1 | D        |
| 17/12/2018 00:00:00 |    1 |      0 |     0 | C        |
| 17/12/2018 00:00:00 |    1 |      0 |     0 | E        |
+---------------------+------+--------+-------+----------+

Demo