我正在尝试计算在不到30分钟且超过30分钟内关闭的订单数。
表结构和示例数据
ORDERID CUSTOMERID ORDERDATE CLOSEDDATE STATUSID
---------------------------------------------------------------------------------
14 1 2018-07-03 11:02:54.000 2018-07-03 13:15:58.000 CLOSED
15 1 2018-07-03 13:22:42.000 NULL DISPATCHED
16 1 2018-07-03 13:26:04.000 NULL DISPATCHED
17 1 2018-07-03 13:27:57.000 2018-07-03 13:28:28.000 CLOSED
18 1 2018-07-03 17:23:45.000 NULL RECEIVED
查询:
SELECT
OUTLETNAME,
COUNT(ORDERID) AS ORDERSCOUNT,
COUNT(DISTINCT(dbo.VW_SALES_SUM.CUSTOMERID)) AS CUSTOMERCOUNT,
COUNT(CASE WHEN DATEDIFF(mi, dbo.VW_SALES_SUM.ORDERDATE, dbo.VW_SALES_SUM.CLOSEDDATE) < 30 AND dbo.VW_SALES_SUM.STATUSID = 'CLOSED'
THEN 1
ELSE 0
END) [LESS 30 (CLOSED)],
COUNT(CASE WHEN DATEDIFF(mi, dbo.VW_SALES_SUM.ORDERDATE, dbo.VW_SALES_SUM.CLOSEDDATE) > 30 AND dbo.VW_SALES_SUM.STATUSID = 'CLOSED'
THEN 1 ELSE 0
END) [Greater 30 (CLOSED)]
FROM
dbo.VW_SALES_SUM
INNER JOIN
dbo.[OUTLET] ON dbo.VW_SALES_SUM.OUTLETCODE = dbo.[OUTLET].CODE
WHERE
dbo.VW_SALES_SUM.ORDERDATE BETWEEN '7/3/2018 11:00:00 AM' AND '7/4/2018 02:00:00 AM'
GROUP BY
OUTLETNAME, dbo.OUTLET.BRAND
ORDER BY
COUNT(ORDERID) DESC
输出:
OUTLETNAME ORDERSCOUNT CUSTOMERCOUNT LESS 30 (CLOSED) IN 30 (CLOSED)
--------------------------------------------------------------------------
shop1 5 1 5 5
从输出中我们可以看到它返回的已关闭订单计数错误,它总是返回订单总数。
输出应如下所示:
OUTLETNAME ORDERSCOUNT CUSTOMERCOUNT LESS 30 (CLOSED) Greater 30 (CLOSED)
-------------------------------------------------------------------------
shop1 5 1 0 2
答案 0 :(得分:1)
而不是同时计算1和0。您要做的就是不同时计算两者。
问题是,按值计数不计入NULL。
但是,当CASE WHEN仅返回值0或1时,COUNT的行为与COUNT(*)相同。由于它不会为COUNT忽略而返回任何NULL。
所以只需删除那些SELECT
OUTLETNAME,
COUNT(ORDERID) AS ORDERSCOUNT,
COUNT(DISTINCT(s.CUSTOMERID)) AS CUSTOMERCOUNT,
COUNT(CASE
WHEN DATEDIFF(mi, s.ORDERDATE, s.CLOSEDDATE) < 30 AND s.STATUSID = 'CLOSED'
THEN 1
END) [LESS 30 (CLOSED)],
COUNT(CASE
WHEN DATEDIFF(mi, s.ORDERDATE, s.CLOSEDDATE) > 30 AND s.STATUSID = 'CLOSED'
THEN 1
END) [Greater 30 (CLOSED)]
FROM dbo.VW_SALES_SUM s
JOIN dbo.[OUTLET] o ON o.CODE = s.OUTLETCODE
WHERE
s.ORDERDATE BETWEEN '7/3/2018 11:00:00 AM' AND '7/4/2018 02:00:00 AM'
GROUP BY OUTLETNAME, o.BRAND
ORDER BY COUNT(ORDERID) DESC
,就可以了。
顺便说一句,使用别名可以缩短您的SQL。
SELECT COUNT(DISTINCT CASE WHEN col1='bar' then col2 END) AS Bars FROM Foo;
您也可以将COUNT替换为SUM。但是COUNT的优点是您可以将其与DISTINCT结合使用,以便仅计算不为NULL的唯一值。
例如:
return redirect('home')->with('success', 'Group is created!');
答案 1 :(得分:0)
使用SUM代替计数
SELECT
OUTLETNAME,
COUNT(ORDERID) AS ORDERSCOUNT,
COUNT(distinct(dbo.VW_SALES_SUM.CUSTOMERID)) as CUSTOMERCOUNT,
SUM(case when DATEDIFF(mi, dbo.VW_SALES_SUM.ORDERDATE, dbo.VW_SALES_SUM.CLOSEDDATE) < 30 and dbo.VW_SALES_SUM.STATUSID='CLOSED' then 1 else 0 end) [LESS 30 (CLOSED)],
SUM(case when DATEDIFF(mi, dbo.VW_SALES_SUM.ORDERDATE, dbo.VW_SALES_SUM.CLOSEDDATE) > 30 and dbo.VW_SALES_SUM.STATUSID='CLOSED' then 1 else 0 end) [Greater 30 (CLOSED)]
FROM
dbo.VW_SALES_SUM
INNER JOIN
dbo.[OUTLET] ON dbo.VW_SALES_SUM.OUTLETCODE = dbo.[OUTLET].CODE
WHERE
dbo.VW_SALES_SUM.ORDERDATE BETWEEN '7/3/2018 11:00:00 AM' AND '7/4/2018 02:00:00 AM'
GROUP BY
OUTLETNAME, dbo.OUTLET.BRAND
ORDER BY
COUNT(ORDERID) DESC