Syntax for nested common-table-expression - tsql

I asked a question for a complex query yesterday, and I was offered an example. I really would like to get it to work but there was a syntax error in it that I can't figure out. Keep in mind that I was just introduced to CTE's earlier this week so hopefully this is an easy one.
I don't think I need to post the full code on here, so I'll just summarize
with cte as (select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnnight),
allhours as (
select 0 as hour, midnight as timestart, dateadd(hour, 1, timestart) as timeend from cte union all
select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight) from cte union all
....
select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from cte union all
)
select ah.hour,...
The (...) denotes unnecessary code that I omitted to make it less messy
But I am getting a syntax error on the parenthesis between select 23 and select ah.hour
"Incorrect syntax near ')'. Expecting SELECT, or '('.
Any help is greatly appreciated.
-J

You had a few syntax errors including a UNION ALL that was not needed at the bottom, and your first SELECT in the allhours was referencing an alias, so try this:
;with cte as
(
select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnight
),
allhours as
(
select 0 as hour, midnight as timestart, dateadd(hour, 1, midnight) as timeend
from cte
union all
select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight)
from cte
union all
select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight)
from cte
)
select *
from allhours
see SQL Fiddle with Demo

You should get rid of the last Union all here
hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from cte union all
)
select ah.hour,...
Also, spell midnight right in the first line

Related

How can i get last 13 weeks in T SQL excluding current week?

I am working on a project and need to pull last 13 weeks of data. I have tried datediff in filter but it is pulling extra weeks. I have already set datefirst to 1 but still not getting desired result.
WHERE clause is
DATEDIFF(WEEK,dt.date_key,getdate())<=13
Try this code:
SELECT date_key FROM tbl WHERE date_key BETWEEN DATEADD(week, -13,GETDATE()) AND DATEADD(week, -1,GETDATE())
I have managed to get the answer. Put below in where clause and it has worked as expected.
d.date_key is my date column.
d.date_key >= DATEADD(dd, 0, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, GETDATE())) - 13, 0)) and d.date_key <= DATEADD(dd, 6, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, GETDATE())) - 1, 0))

Sort Date Names Accurately by Partition

I have the following data:
with cte (id,[months]) as (
select 1, 'July 2019' union all
select 2, 'July 2019' union all
select 3, 'July 2019' union all
select 4, 'July 2019' union all
select 5, 'August 2019' union all
select 6, 'August 2019' union all
select 7, 'September 2019' union all
select 8, 'October 2019' union all
select 9, 'November 2019' union all
select 10, 'December 2019' union all
select 11, 'January 2020' union all
select 12, 'January 2020' union all
select 13, 'January 2020' union all
select 14, 'January 2020' union all
select 15, 'February 2020' union all
select 16, 'March 2020' union all
select 17, 'March 2020' union all
select 18, 'April 2020' union all
select 19, 'May 2020' union all
select 20, 'June 2020'
)
I require to create a Sort Column that ranks all the same months with the same number.
The problem I experienced with the following code is, it does not sort correctly and also does not provide me with the expected results:
select
*
, dense_rank() over (partition by months order by id) Sort
from cte
Current Results:
My expected results:
How should I change my script to achieve this?
After a lot of struggle, I managed to resolve this with this script:
select
*
, convert(date,'01 '+Months) MonthsConvertedToDate
, dense_rank() over (order by convert(date,'01 '+Months)) Sort
from cte
order by sort,id
Results:
See demo here
I am however open to better suggestions :-)

Select all rows 7 days prior from a specific date

I want to get all rows 7 days prior from 01/09/2017
I know I can do
Load_DTM <= '2017-01-09' and Load_DTM >= '2017-01-02'
But can I not use DateAdd or DatePart?
i.e. DateAdd(dd, -7, '2017-01-09')
Load_DTM BETWEEN DATEADD(dd,-7,'2017-01-09') AND '2017-01-09 11:59:59'
ought to work.
You should be able to do exactly what you showed in your example:
SELECT * FROM Table WHERE DateField = DATEADD(DAY, -7, '2017-09-01')
Since running:
SELECT DATEADD(DAY, -1, GETDATE())
Gives you:
2017-03-15 19:26:29.833

How to get Quarter from a date in Firebird SQL

I can easily get total sales in this month and previous month.
SELECT ‘This Mount’, SUM(Price) FROM Sales
WHERE EXTRACT(MONTH FROM OrderDate) = EXTRACT(MONTH FROM CURRENT_DATE)
AND EXTRACT(YEAR FROM OrderDate) = EXTRACT(YEAR FROM CURRENT_DATE)
Union All
SELECT ‘Previous Month’, SUM(Price) FROM Sales
WHERE EXTRACT(MONTH FROM OrderDate) = EXTRACT(MONTH FROM CURRENT_DATE)
AND EXTRACT(YEAR FROM OrderDate) = EXTRACT(YEAR FROM CURRENT_DATE)
I want to get the total sales in this quarter and previous quarter.
Getting quarter from a date is very easy with MS-SQL as follows:
SELECT DATEPART(QUARTER, #date)
How can I do this with Firebird?
Use DECODE function in conjunction with EXTRACT:
SELECT
DECODE(EXTRACT(MONTH FROM <date_field>),
1, 'I',
2, 'I',
3, 'I',
4, 'II',
5, 'II',
6, 'II',
7, 'III',
8, 'III',
9, 'III',
'IV')
FROM
<some_table>
Or just
SELECT
(EXTRACT(MONTH FROM <date_field>) - 1) / 3 + 1
FROM
<some_table>
SELECT dates,
EXTRACT(MONTH from dates) as SalesMonth,
floor(((EXTRACT(MONTH from dates)-1) / 3.0 + 1)) as QTR
from CustomerPO
where ((dates > '1/1/2016') and (dates < '12/31/2016'))
order by dates
Here, 'dates' is the field name of Order table 'CustomerPO'
SELECT dates,
EXTRACT(MONTH from dates) as SalesMonth,
ceil(EXTRACT(MONTH from dates) / 3) as QTR
from CustomerPO
where ((dates > '1/1/2016') and (dates < '12/31/2016'))
order by dates

Getting the start date and end date of all weeks by giving the year

I have a query which displays a set of 52 numbers along with the respective dates of that week
SELECT kkk, TO_CHAR (start_date, 'DD-MON-YYYY'),
TO_CHAR (start_date + 6, 'DD-MON-YYYY') AS end_day
FROM (SELECT TRUNC (TRUNC (TO_DATE ('2014', 'YYYY'), 'YYYY') + 1 * 7,
'IW'
)
- 1 start_date,
ROWNUM AS kkk
FROM DUAL
CONNECT BY ROWNUM <= 52);
but the problem with this query is that I am only getting the first week dates but not for the next consecutive weeks.Please help
Try like this,
SELECT kkk,
TO_CHAR(start_date, 'DD-MON-YYYY') start_date,
TO_CHAR(start_date + 6, 'DD-MON-YYYY') end_day
FROM(
SELECT TRUNC(Trunc(to_date('2014', 'YYYY'),'YYYY')+ LEVEL * 7,'IW')-1 start_date ,
ROWNUM kkk
FROM duaL
CONNECT BY LEVEL <= 52
);
Instead of ROWNUM you can also use LEVEL, Like,
SELECT TRUNC(Trunc(to_date('2014', 'YYYY'),'YYYY')+ LEVEL * 7,'IW')-1 start_date ,
level kkk
FROM duaL
CONNECT BY LEVEL <= 52