SQL Server returns unexpected week number - sql-server-2008

I have some orders in a table and the last order date of 2011 is 20th Dec.
I'm using a sql command to calculate the number of orders in a given week:
SELECT CONVERT(VARCHAR(3),DATENAME(week,convert(datetime,order_date,103))) AS week,
COUNT(1) as orders
FROM order_table
where DATENAME(YEAR,convert(datetime,order_date,103)) = '2011'
GROUP BY CONVERT(VARCHAR(3),DATENAME(week,convert(datetime,order_date,103)))
order by week asc
It returns me the some of the following results:
Week | Orders
41 | 42
42 | 110
43 | 115
...
...
51 | 155
52 | 15
The trouble with this is is that the last order date of 2011 as mentioned that I have is 20th Dec 2011, which can't be week 52 so must be week 51.
I've got some other stats(off another system, not SQL server) which giving me some other figures and the last week on it is 51 which I have no doubt is correct. So there's going to be a queries if people are looking both!
Anyone have any idea or know how to sort this?
Thanks,

The iso_week of 20th Dec 2011 is 51. So maybe that is what you need.
SELECT datepart(iso_week, '2011-12-20')

SQL Counts a week as Sunday-Saturday, you can use the script below to see how the weeks break out for 2011. The 1st of January is a Saturday, which means the first week is only 1 day. There are 53 SQL weeks in 2011, and 53 weeks in most years
DECLARE #dStartDate DATETIME
SET #dStartDate = '01/01/2011'
WHILE #dStartDate < '01/01/2012'
BEGIN
PRINT CONVERT(VARCHAR, #dStartDate, 101)
+ ' : '
+ CONVERT(VARCHAR, DATEPART(WEEK, #dStartDate))
+ ' : '
+ DATENAME(DW, #dStartDate)
SET #dStartDate = #dStartDate + 1
END
If you want to change the day SQL counts as the first of the week, you can use the DATEFIRST command
http://msdn.microsoft.com/en-us/library/ms181598.aspx

SELECT DatePart(WEEK,order_date) AS WeekOfYear
FROM order_table
Should give you the week number.

So do
Select * from order_table Where DatePart(Week, order_date) = 52
See what is week 52 not what you think is 52.
PS Given you are starting week 1 on the 1/1 it's not possible to have a 52 week year, unless 1 and or 52 are not seven day weeks.

Related

Add weekend values to Monday SQL

I am working in mySQL and I currently have a count of total orders by day, but I would like to add Saturday and Sunday orders to Monday then remove Saturday and Sunday values. I have done some research on this but I cannot seem to find anything similar to what I am trying to do.
My current data table looks like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-8-2020 24
8-9-2020 33
8-10-2020 18
8-11-2020 10
8-12-2020 25
8-13-2020 15
I need it to look something like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-10-2020 75
8-11-2020 10
8-12-2020 25
8-13-2020 15
In this one the Daily counts for the 8th and 9th are added to the 10th, then removed, because they are weekend days. Thank you in advance for your help!
Consider using a case expression to adjust the date:
select
case weekday(date)
when 5 then date + interval 2 day
when 6 then date + interval 1 day
else date
end as new_date,
sum(daily_count) as daily_count
from mytable
group by new_date

How to get week number and date of that week between two dates using MySQL

I am using MySQL And I have two dates "From date" and "To date", and based on these date i want to get week number and dates of that week between "To" and "From" Dates.
I have tried the following mysql query.
SELECT count(*) as count,
CONCAT(DATE_FORMAT(DATE_ADD(FROM_DAYS(TO_DAYS(FROM_UNIXTIME(`webform_submissions`.`submitted`)) -MOD(TO_DAYS(FROM_UNIXTIME(`webform_submissions`.`submitted`)) -1, 7)),INTERVAL -6 DAY),'%M %d'), ' - ' ,DATE_FORMAT(FROM_DAYS(TO_DAYS(FROM_UNIXTIME(`webform_submissions`.`submitted`)) -MOD(TO_DAYS(FROM_UNIXTIME(`webform_submissions`.`submitted`)) -1, 7)),'%M %d')) as date ,
CONCAT(YEAR(FROM_UNIXTIME(`webform_submissions`.`submitted`)), '/', WEEK(FROM_UNIXTIME(`webform_submissions`.`submitted`))) as week
FROM `webform_submissions`
where `webform_submissions`.`nid` = 121
AND DATE_FORMAT(FROM_UNIXTIME(`webform_submissions`.`submitted`), '%Y-%m-%d') between '2019-11-01' and '2019-12-03'
GROUP BY week
ORDER BY `webform_submissions`.`submitted` ASC
The following result is display according to above query.
But it seems that it gives wrong result because week number 43 lies between 21-27 Oct and i want to get result between between '2019-11-01' and '2019-12-03'.
Expected output should be like the screenshot. Because From date "2019-11-01" lies between Oct 28- Nov 03 (Week 44). so records should be start from 44 week number.
Any Idea how to get correct number of week and dates?
Here's a somewhat easier to read version of your query (using nested subqueries since MySQL 5.6 doesn't support CTEs) and using DATE_FORMAT with the %x/%v format to generate the week to match your expected result (October 28 is the start of week 44). Note I've added a MIN into the generation of date so that the query will still work in MySQL 5.7 with SQL mode ONLY_FULL_GROUP_BY.
SELECT COUNT(*) AS count,
CONCAT(DATE_FORMAT(MIN(startofweek), '%M %d'),
' - ',
DATE_FORMAT(MIN(startofweek) + INTERVAL 6 DAY, '%M %d')) AS date,
week
FROM (SELECT submitted - INTERVAL (dayofweek + 6) % 7 DAY AS startofweek,
week
FROM (SELECT nid,
DATE(FROM_UNIXTIME(submitted)) AS submitted,
DATE_FORMAT(FROM_UNIXTIME(submitted), '%w') AS dayofweek,
DATE_FORMAT(FROM_UNIXTIME(submitted), '%x/%v') AS week
FROM webform_submissions
WHERE nid = 121
AND DATE(FROM_UNIXTIME(submitted)) BETWEEN '2019-11-01' AND '2019-12-03'
) AS dates
) AS ws
GROUP BY week
Output (for my sample data)
count date week
3 October 28 - November 03 2019/44
4 November 04 - November 10 2019/45
Demo on dbfiddle
Try to set the second parameter of WEEK() according to your expected result.
With the second parameter you can set the mode with wich you specify wether the week starts with sunday or monday, the week numbers starts with 0 or 1 and the rule defining the first week of the year.
See https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week

Group by hour showing breakdown for each day within date range MYSQL

I'm trying to create a query to show the breakdown of leads relating to finance contracts grouped by hour.
Here's an example of what I have so far for hours:
SELECT CONCAT(HOUR(received), ':00-', HOUR(received)+1, ':00') AS Hours,
COUNT(*) as `leads`
FROM (digital_lead)
WHERE `received` BETWEEN '2014-11-01 00:00:00' AND '2014-11-24 00:00:00'
GROUP BY HOUR(received)
And here's the result ....
Hours usage
0:00-1:00 36
1:00-2:00 25
2:00-3:00 16
3:00-4:00 4
4:00-5:00 7
5:00-6:00 8
6:00-7:00 13 // etc all the way to 23:00 - 24:00
OK - so that seems to work, however, it aggregates all of the leads for that time slot over the course of the period set in the BETWEEN statement. I would like to be able to show the breakdown per hour for each day within the period range.
So that would look something like:
Date Hours leads
2014-11-01
0:00-1:00 36
1:00-2:00 25
2:00-3:00 16
3:00-4:00 4
4:00-5:00 7
5:00-6:00 8
6:00-7:00 13 // etc all the way to 23:00 - 24:00
So each date would be displayed and then the hours for that day and so forth.
Thanks.
Group by date as well:
SELECT DATE(received), HOUR(received), ...
...
GROUP BY DATE(received), HOUR(received)
Since you're grouping by hour() only, you'll essentialy be getting
Hour
1 sum of leads in hour 1 of jan 1, jan 2, jan 3, ... dec 31
2 sum of leads in hour 2 of jan 1, jan 2, jan 3, ... dec 31
Rather than
Jan 1 Hour 1 sum of leads for just that one hour on the one day
Jan 1 Hour 2 sum of leads for just that one hour on the one day
..
Dec 31 Hour 23 sum of leads

MySQL query results with weekday between 2 dates

I need a query to get results from a table that has 2 columns
Column startdt (datetime), Column enddt (datetime)
there are some records with startdt 2013-07-19 and enddt 2013-07-29
I need to get the records with weekday = 1 (Tuesday)
the record with date 2013-07-19 is weekday 4 and ends 2013-07-29 which is 0
Actually i want to get the results that has for weekday Monday or another weekday.
You can check the above link for an example
http://sqlfiddle.com/#!2/a80ce/1
If you don't understand what i want to do let me explain. I have an event that starts July 15 and ends July 25. (Starts Monday and ends Thursday) The user selects one of the week days (Monday, Tuesday etc). If he select Tuesday then i want the query that will get all events that are active in Tuesday.
I already found the answer so if anyone want to check it
SELECT articleid,startdt,enddt,dayofweek(startdt), DATEDIFF(enddt,startdt) datedf
FROM events
WHERE (dayofweek(events.startdt) <= 3 AND dayofweek(events.enddt) >= 3)
OR DATEDIFF(enddt,startdt) >=6
(3 is the number of the weekday "Tuesday")
How about using the comments that other people gave you and use a query that combines both dayofweek and a simple greater/smaller/equal syntax as follows:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6
This gives the following results if the user specified a friday (= 6):
ARTICLEID STARTDT ENDDT
4 July, 12 2013 00:00:00+0000 July, 26 2013 00:00:00+0000
6 July, 16 2013 00:00:00+0000 July, 20 2013 00:00:00+0000
I do think that you are better of using dayofmonth however as this (maybe just to me) makes it clearer, possibly combining the use of both to ensure that it's active on a friday.
The OP indicates that events which are in the history should also be retrieved and as such the following query does what he wants:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6 OR DATEDIFF(enddt,startdt) >=6
How about this solution:
first you convert the day of week in format that 6 is Saturday and 7 is sunday(it's easier for me)
if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
after that you calc the days from the start_date needed to reach some of the weekdays
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
finally you make sure that the difference in days between the two dates is no less that the above calculation
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1) <= datediff(o.end_date, o.start_date)

MySql Query- Date Range within a Date Range

I use mySql 5 and IIS.
I have products, that have a start date field and an end date field.
I need to run a query that will take user entered Start and End dates, and output the number of days that the product ran within the date range.
Example:
Offer1 - July 1 2011 thru July 31 2011
Query - July 1 2011 thru Sept 15 2011
Results = 31
Example:
Offer1 - July 1 2011 thru July 31 2011
Query - July 1 2011 thru July 15 2011
Results = 15
If your products have a start_date and an end_date and your query has a qstart_date and a qend_date, then we want the number of days between:
GREATEST(start_date, qstart_date)
and
LEAST(end_date,qend_date)
. In MySQL I think this looks like
1 + DATEDIFF ( 'd' , GREATEST(start_date, qstart_date) , LEAST(end_date,qend_date) )
And you'll want to ignore negative numbers, replacing them with "0".