SQL中填充没有数据的行为零。

huangapple go评论71阅读模式
英文:

SQL Fill in 0 for the rows with no data

问题

I can provide a translation of the code portion for you. Here it is:

with mycte as
(
    SELECT 0 AS MyHour
    UNION ALL
    SELECT MyHour + 1
    FROM mycte 
    WHERE MyHour + 1 < 24
)
SELECT h.SalesDay, FORMAT(DATEADD(hour, mycte.MyHour, '00:00'), 'HH:mm') AS SalesByHour, COALESCE(ReceiptCount, 0) AS HourlySales FROM mycte
LEFT JOIN
(
SELECT
   DATENAME(WEEKDAY, TRANDATETIME) AS SalesDay,
   DATEPART(hour, TRANDATETIME) AS SalesByHour,
   COUNT(REF) as ReceiptCount
FROM [RC_BACK].[dbo].[TRAN]
WHERE TRANCODE = 'SA'
GROUP BY DATENAME(WEEKDAY, TRANDATETIME), DATEPART(hour, TRANDATETIME)
) h
ON h.SalesByHour = mycte.MyHour
ORDER BY h.SalesDay, SalesByHour ASC

Please let me know if you need any further assistance.

英文:

I am trying to generate a table that have receipt count group by days of the week and every hour of a day. I want the table include the day and hour that have no record and will fill it in with 0 for the receipt count. For example, I want the query to return a table with something like this:

SalesDay SalesByHour ReceiptCount
Monday 00:00 0
Monday 01:00 0
Monday 02:00 0
Monday 03:00 0
Monday 04:00 0
Monday 05:00 200
Monday 06:00 200
Monday 07:00 200
Monday 08:00 200
Monday 09:00 0
Monday 10:00 200
Monday 11:00 200
Monday 12:00 0
Monday 13:00 200
Monday 14:00 200
Monday 15:00 200
Monday 16:00 0
Monday 17:00 200
Monday 18:00 200
Monday 19:00 200
Monday 20:00 200
Monday 21:00 200
Monday 22:00 200
Monday 23:00 0

And the rest of the table will resume with Tuesday, Wednesday and so on until Sunday with every hour of a day in the table as above. The day of the week is generated with DATENAME() function and the hours of the day is generated with CTE as I don't have a table for the weekdays and hours. My query as of now will only return results with days and hours that have records in the database. My query is as below:

with mycte as
(
    SELECT 0 AS MyHour
    UNION ALL
    SELECT MyHour + 1
    FROM mycte 
    WHERE MyHour + 1 &lt; 24
)
SELECT h.SalesDay, FORMAT(DATEADD(hour,mycte.MyHour,&#39;00:00&#39;),&#39;HH:mm&#39;) AS SalesByHour, COALESCE(ReceiptCount,0) AS HourlySales FROM mycte
LEFT JOIN
(
SELECT
   DATENAME(WEEKDAY, TRANDATETIME) AS SalesDay,
   DATEPART(hour, TRANDATETIME) AS SalesByHour,
   COUNT(REF) as ReceiptCount
FROM [RC_BACK].[dbo].[TRAN]
WHERE TRANCODE = &#39;SA&#39;
GROUP BY DATENAME(WEEKDAY, TRANDATETIME), DATEPART(hour, TRANDATETIME)
) h
ON h.SalesByHour = mycte.MyHour
ORDER BY h.SalesDay, SalesByHour ASC

and results are as below:

SQL中填充没有数据的行为零。

SQL中填充没有数据的行为零。

What do I need to add for my query so that it will have the results that I want?

答案1

得分: 1

以下是代码的翻译部分:

正如 @DaleK 所指出的,理想的解决方案是使用一种包含日期和小时的日历表,并在代码中使用它。以下是使用您已经使用的 CTE 方法的解决方案:

WITH cte_hours
AS (
    SELECT 0 AS [hour]
    UNION ALL
    SELECT [hour] + 1
    FROM cte_hours
    WHERE [hour] + 1 < 24
)
, cte_days
AS (
	SELECT daynm, [dayname]
    FROM (
	VALUES 
             (0,'星期一')  ,(1,'星期二') ,(2,'星期三') ,(3,'星期四') ,(4,'星期五') ,(5,'星期六') ,(6,'星期日')
	)  a(daynm, [dayname])
)
/*示例销售数据集*/
, cte_sales
AS (
	SELECT [hour], [dayname], [hourlysales]
    FROM (
	VALUES 
             (4,'星期一', 100), (14,'星期一', 110), (5,'星期一', 20), (6,'星期一', 10), (21,'星期一', 3),(3,'星期一', 50)
            ,(11,'星期二', 3), (12,'星期二', 15),  (9,'星期二', 155), (2,'星期二', 25)
            ,(12,'星期三', 125) ,(14,'星期三', 9) ,(11,'星期三', 95) 
            ,(13,'星期四', 42), (23,'星期四', 342), (6,'星期四', 123)
            ,(20,'星期五', 9),(4,'星期五', 93)
            ,(15,'星期六', 32),(12,'星期六', 322),(16,'星期六', 132),(19,'星期六', 2),(5,'星期六', 3),(3,'星期六', 323)
            ,(18,'星期日', 65) ,(13,'星期日', 165) ,(1,'星期日', 5) ,(14,'星期日', 665)
	)  a([hour], [dayname], [hourlysales])
) 
SELECT dy.[dayname], hr.[hour] ,FORMAT(DATEADD(hour,hr.[hour],'00:00'),'HH:mm') As formathr
	, ISNULL([hourlysales], 0) AS [hourlysales]
FROM cte_hours hr
CROSS JOIN cte_days dy
LEFT OUTER JOIN cte_sales sl ON sl.[hour] =  hr.[hour] and sl.[dayname] =  dy.[dayname]
ORDER BY dy.daynm, hr.[hour];

希望这对您有所帮助。如果您需要更多帮助,请告诉我。

英文:

As @DaleK indicated an ideal solution would be to use a sort of calendar table with days and hours and use it in the code. Here is a solution using the CTE route you have used :

WITH cte_hours
AS (
SELECT 0 AS [hour]
UNION ALL
SELECT [hour] + 1
FROM cte_hours
WHERE [hour] + 1 &lt; 24)
,cte_days
AS (
SELECT daynm, [dayname]
FROM (
VALUES 
(0,&#39;Monday&#39;)  ,(1,&#39;Tuesday&#39;) ,(2,&#39;Wednesday&#39;) ,(3,&#39;Thursday&#39;) ,(4,&#39;Friday&#39;) ,(5,&#39;Saturday&#39;) ,(6,&#39;Sunday&#39;)
)  a(daynm, [dayname])
)
/*Sample sales data set */
, cte_sales
AS (
SELECT [hour], [dayname], [hourlysales]
FROM (
VALUES 
(4,&#39;Monday&#39;, 100), (14,&#39;Monday&#39;, 110), (5,&#39;Monday&#39;, 20), (6,&#39;Monday&#39;, 10), (21,&#39;Monday&#39;, 3),(3,&#39;Monday&#39;, 50)
,(11,&#39;Tuesday&#39;, 3), (12,&#39;Tuesday&#39;, 15),  (9,&#39;Tuesday&#39;, 155), (2,&#39;Tuesday&#39;, 25)
,(12,&#39;Wednesday&#39;, 125) ,(14,&#39;Wednesday&#39;, 9) ,(11,&#39;Wednesday&#39;, 95) 
,(13,&#39;Thursday&#39;, 42), (23,&#39;Thursday&#39;, 342), (6,&#39;Thursday&#39;, 123)
,(20,&#39;Friday&#39;, 9),(4,&#39;Friday&#39;, 93)
,(15,&#39;Saturday&#39;, 32),(12,&#39;Saturday&#39;, 322),(16,&#39;Saturday&#39;, 132),(19,&#39;Saturday&#39;, 2),(5,&#39;Saturday&#39;, 3),(3,&#39;Saturday&#39;, 323)
,(18,&#39;Sunday&#39;, 65) ,(13,&#39;Sunday&#39;, 165) ,(1,&#39;Sunday&#39;, 5) ,(14,&#39;Sunday&#39;, 665)
)  a([hour], [dayname], [hourlysales])
) 
SELECT dy.[dayname], hr.[hour] ,FORMAT(DATEADD(hour,hr.[hour],&#39;00:00&#39;),&#39;HH:mm&#39;) As formathr
, ISNULL([hourlysales], 0) AS [hourlysales]
FROM cte_hours hr
CROSS JOIN cte_days dy
LEFT OUTER JOIN cte_sales sl ON sl.[hour] =  hr.[hour] and sl.[dayname] =  dy.[dayname]
ORDER BY dy.daynm, hr.[hour];

huangapple
  • 本文由 发表于 2023年5月26日 14:50:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338280.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定