Output Sum of some column in week intervals throughout a year, week dates consistent with day

我的未来我决定 提交于 2020-01-15 10:33:26

问题


I need some help as I am stuck. This is using SQL and Coldfusion. Basically I have a table which list a completion of certain tickets along with what date they were marked complete. This table has district and area for example, which is used in the GROUP BY. So I want to count every ticket that was done on every week of the year, the user selects for example running the report. I will list a little of the SQL I have at the moment.

 SELECT                                           
    SUM(CASE WHEN DATEPART(ww, completionDate) = 1 THEN 1 ELSE 0 END) AS [Jan1-7],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 2 THEN 1 ELSE 0 END) AS [Jan8-14],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 3 THEN 1 ELSE 0 END) AS [Jan15-21],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 4 THEN 1 ELSE 0 END) AS [Jan22-31]    
    SUM(CASE WHEN DATEPART(ww, completionDate) = 5 THEN 1 ELSE 0 END) AS [Feb1-7],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 6 THEN 1 ELSE 0 END) AS [Feb8-14],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 7 THEN 1 ELSE 0 END) AS [Feb15-21],
    SUM(CASE WHEN DATEPART(ww, completionDate) = 8 THEN 1 ELSE 0 END) AS [Feb22-28],

As you can see I am basically trying to grab which week of the year the completionDate was and summing that in its own column. It should be in this format unless someone has a better suggestion. The issue is for example, 2/18/2013 for example, SQL is telling me that would be the 8th week of 2013, whereas my code would SUM that in the FEB15-21, which is the 7th week according to my code. The report I need is to show the month in a top header, and then show each week in the next header of that month, then basically do a count of every ticket completed in that week. So the weeks/months need to be columns.

I have read some CF functions and all, but just not sure how to utilize them to get what I need. Is there either a way to dynamically SUM these dates ensuring they are SUMMED in the correct column based on the week, or use Coldfusion to handle this part? But I am not too sure on the ColdFusion part either, so if possible, any suggestion on either using SQL or CF and maybe helping me out on the code part would be really really appreciated.

Thanks!!


回答1:


I recommend creating a database table where the primary key is the date. Other fields in this table would include the week string (Jan 7 - 13) plus anything else, holidays, fiscal information, etc that you need.

You'll need a maintenance script for some things and you might have to do the holidays part manually. It's what we do with our data warehouse.

It makes the report you are currently attempting very simple.




回答2:


I'm not 100% sure I am following correctly but why not give this query a shot. This will count up frequencies for each week/month combination allowing you to split it up by week or month as desired on output. You can then use CF logic to determine limiting dates for output purposes.

SELECT

    -- Get the week and month of each row
    MONTH(completionDate) AS monthOfYear,
    WEEK(completionDate) AS weekOfYear,

    -- Count how many rows are in this group
    COUNT(*) AS frequency

FROM yourTable AS yt

-- If you are only interested in a specific date range, chuck in something like this
WHERE yt.completionDate BETWEEN DATE('2013-01-01') AND ('2013-12-30')

-- Order by month and then week, so that week 4 in Jan comes before week 4 in Feb
GROUP BY
    monthOfYear ASC,
    weekOfYear ASC

Hopefully this is of help, if this isn't quite the sort of thing you had in mind please clarify the question.

If this is for a very large table and you are just interested in end of day stats, then consider running something like the following after every day into a table with a simple structure with columns statsDate DATE NOT NULL PK and statsFrequency INTEGER UNSIGNED NOT NULL

INSERT INTO yourStatsTable(
    statsDate,
    statsFrequency
)
SELECT
    DATE(completionDate),
    COUNT(*)
FROM yourTable AS yt
WHERE yt.completionDate >= SUBDATE(CURRENT_DATE,1) 
AND yt.completionDate < CURRENT_DATE
ON DUPLICATE KEY UPDATE statsFrequency = VALUES(statsFrequency)

This will then give you a table with tallies for previous days that can be queried without hitting the main table (but again only do this if it's a big/busy table and generating them on the fly would not be viable)




回答3:


I think the part that's confusing you is how MSSQL is treating the week numbers. They're all Mon-Sun week formats. Week 1 in this case begins on the Monday 12/31/2012 to Sunday 1/6/13 (and not 1/1/2013 to 1/7/2013 you're assuming), Week 2: 1/7/13 to 1/13/13, and so on... 2/18/2013 is on the eighth week of the year because it starts the 8th week (a Monday).

You'll want to use something like:

DATEADD(ww, DATEDIFF(ww,0,completionDate), 0) AS [Start Of Week],
DATEADD(s,-1,DATEADD(ww, DATEDIFF(ww,0,GETDATE())+1,0)) as [End Of Week]

to get the start and end dates and use it in your group by clause and summation.

To match your code, though, you can add the number of offset days to [Start Of Week] and [End Of Week] to get your ranges. In 2013, that offset will be 1 day as 1/1/2013 (human start of year) - 12/31/2012 (sql start of year). The dates will all match up with your [Jan1-7] week format that way.

Hope this helps. -Minh



来源:https://stackoverflow.com/questions/15539719/output-sum-of-some-column-in-week-intervals-throughout-a-year-week-dates-consis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!