sql pivot month result to year format - postgresql

How can I get the year column information,
which is not clear like the month, in the header?
select
isnull (group_info, 'grand total') as 'group_definition',
isnull (sum (case datepart(month, shipment_date) when 1 then amount end),0) as 1,
isnull (sum (case datepart(month, shipment_date) when 2 then amount end),0) as 2,
isnull (sum (case datepart(month, shipment_date) when 3 then amount end),0) as 3,
isnull (sum (case datepart(month, shipment_date) when 4 then amount end),0) as 4,
isnull (sum (case datepart(month, shipment_date) when 5 then amount end),0) as 5,
isnull (sum (case datepart(month, shipment_date) when 6 then amount end),0) as 6,
isnull (sum (case datepart(month, shipment_date) when 7 then amount end),0) as 7,
isnull (sum (case datepart(month, shipment_date) when 8 then amount end),0) as 8,
isnull (sum (case datepart(month, shipment_date) when 9 then amount end),0) as 9,
isnull (sum (case datepart(month, shipment_date) when 10 then amount end),0) as 10,
isnull (sum (case datepart(month, shipment_date) when 11 then amount end),0) as 11,
isnull (sum (case datepart(month, shipment_date) when 12 then amount end),0) as 12,
isnull (sum (amount),0) as grandtotal
from invoice
group by groupıng sets
((datepart(year, shipment_date), group_info), ());

Related

Show every week of the Year even if there is no data

I have query that pulls data by week and groups it together. But i does not display weeks that doesn't have any data. I want show all weeks even if they don't have data as null maybe
Here is the query if someone can help me with this it will awesome
SELECT
DATEADD (week, datediff(week, 0, StartDate), -1) as 'WeekOf'
,DATEADD (week, datediff(week, 0, StartDate), +5) as 'to'
,DATEPART(wk, StartDate) as 'WeekNumber'
FROM [DESOutage].[dbo].[OPSInterruption]
Where StartDate > '2020-01-01' and EndDate <'2020-02-01'
Group by DATEADD (week, datediff(week, 0, StartDate), -1),DATEPART(wk, StartDate),DATEADD (week, datediff(week, 0, StartDate), +5)
***************Output***************
As you could see week 2 and 4 is missing out since there is no data being returned. I would still like to see week 2 and 4 in the output with maybe 0 as result.
WeekOf to WeekNumber
2019-12-29 00:00:00.000 2020-01-04 00:00:00.000 1
2020-01-12 00:00:00.000 2020-01-18 00:00:00.000 3
2020-01-26 00:00:00.000 2020-02-01 00:00:00.000 5
You probably need a calendar table. Here is a quick way of generating one, with an untested implementation of your code. I am assuming that the StartDate may contain a time component thus the need to coalesce the dates.
DECLARE #StartYear DATETIME = '20200101'
DECLARE #days INT = 366
;WITH
E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 1*10^1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), -- 1*10^2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), -- 1*10^4 or 10,000 rows
E8(N) AS (SELECT 1 FROM E4 a, E4 b), -- 1*10^8 or 100,000,000 rows
Tally(N) AS (SELECT TOP (#Days) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E8),
Calendar AS (
SELECT StartOfDay = DATEADD(dd,N-1,#StartYear),
EndOfDay = DATEADD(second, -1, DATEADD(dd,N ,#StartYear))
FROM Tally)
SELECT DATEADD (week, datediff(week, 0, COALESCE(x.StartDate, c.StartOfDay) ), -1) as 'WeekOf'
, DATEADD (week, datediff(week, 0, COALESCE(x.StartDate, c.StartOfDay)), +5) as 'to'
, DATEPART(wk, COALESCE(x.StartDate, c.StartOfDay)) as 'WeekNumber'
FROM Calendar c
INNER JOIN [DESOutage].[dbo].[OPSInterruption] x
ON x.StartDate > c.StartOfDay AND x.StartDate <= c.EndOfDay
WHERE c.StartOfDay > '2020-01-01' AND c.StartOfDay <'2020-02-01'
GROUP BY DATEADD (week, datediff(week, 0, COALESCE(x.StartDate, c.StartOfDay)), -1),
DATEPART(wk, COALESCE(x.StartDate, c.StartOfDay)),
DATEADD (week, datediff(week, 0, COALESCE(x.StartDate, c.StartOfDay)), +5)

How to convert multiple string formats into one date format in BigQuery?

I have a date column say "payment date" in my data which has multiple string formats such as ddmmyyyy,ddmyyyy and yyyymmdd. Does anyone know how I can convert all of these into a unified date format like dd-mm-yyyy in BigQuery?
Below example is for BigQuery Standard SQL:
#standardSQL
SELECT payment_date,
FORMAT_DATE('%d-%m-%Y', CASE LENGTH(payment_date)
WHEN 7 THEN
SAFE.DATE(
SAFE_CAST(SUBSTR(payment_date, -4) AS INT64),
SAFE_CAST(SUBSTR(payment_date, 3, 1) AS INT64),
SAFE_CAST(SUBSTR(payment_date, 1, 2) AS INT64)
)
WHEN 8 THEN
CASE
WHEN EXTRACT(YEAR FROM date_ddmmyyyy) > 2000 THEN date_ddmmyyyy
ELSE date_yyyymmdd
END
ELSE NULL
END) formatted_payment_date
FROM `project.dataset.table`,
UNNEST([STRUCT<date_ddmmyyyy DATE, date_yyyymmdd DATE>(
SAFE.PARSE_DATE('%d%m%Y', payment_date),
SAFE.PARSE_DATE('%Y%m%d', payment_date)
)])
You can test and play with above using dummy data as below
#standradSQL
WITH `project.dataset.table` AS (
SELECT 1 id, '11112011' payment_date UNION ALL
SELECT 2, '1112011' UNION ALL
SELECT 3, '20111111' UNION ALL
SELECT 4, '20112011' UNION ALL
SELECT 5, '20110228'
)
SELECT id, payment_date,
FORMAT_DATE('%d-%m-%Y', CASE LENGTH(payment_date)
WHEN 7 THEN
SAFE.DATE(
SAFE_CAST(SUBSTR(payment_date, -4) AS INT64),
SAFE_CAST(SUBSTR(payment_date, 3, 1) AS INT64),
SAFE_CAST(SUBSTR(payment_date, 1, 2) AS INT64)
)
WHEN 8 THEN
CASE
WHEN EXTRACT(YEAR FROM date_ddmmyyyy) > 2000 THEN date_ddmmyyyy
ELSE date_yyyymmdd
END
ELSE NULL
END) formatted_payment_date
FROM `project.dataset.table`,
UNNEST([STRUCT<date_ddmmyyyy DATE, date_yyyymmdd DATE>(
SAFE.PARSE_DATE('%d%m%Y', payment_date),
SAFE.PARSE_DATE('%Y%m%d', payment_date)
)])
ORDER BY id
with result as:
Row id payment_date formatted_payment_date
1 1 11112011 11-11-2011
2 2 1112011 11-01-2011
3 3 20111111 11-11-2011
4 4 20112011 20-11-2011
5 5 20110228 28-02-2011

Build the calendar table for current year including weeknum divided to semester

for the below query i need divide the semesters starting from 1 to 26 .. first semester as 1 to 26 weeks and first semester should start from again 1 to 26
Any help is greating appreciated
DECLARE #StartDate DATETIME
DECLARE #CutoffDate DATETIME
SET #StartDate = Dateadd(yy, Datediff(yy, 0, Getdate()), 0)
SET #CutoffDate = Dateadd(yy, Datediff(yy, 0, Getdate()) + 1, -1)
SELECT day,
[week nu],
semester,
[semester week nu]
INTO #currentdates
FROM (SELECT Day = Dateadd(day, rn - 1, #StartDate),
Datepart(week, Dateadd(day, rn - 1, #StartDate)) [Week nu],
CASE
WHEN Month(Dateadd(day, rn - 1, #StartDate)) <= 6 THEN
'First Semester'
ELSE 'Second Semester'
END AS Semester,
Datepart(week, Dateadd(day, rn - 1, #StartDate)) AS
[Semester Week nu]
FROM (SELECT TOP (Datediff(day, #StartDate, #CutoffDate)) rn =
Row_number()
OVER (
ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]) AS x) AS y;
I've got a couple of changes, first, you need to add 1 to your last datediff, your last date was December 30, not 31!
Second of all, I just get the date and week number in the first subselect, and then use these ine case statements for the select
The semester number is if week nu<=26,
The semester week nu is week nu if week nu<=26 else wwek nu -26
DECLARE #StartDate datetime DECLARE #CutoffDate datetime
SET #StartDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)
SET #CutoffDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1)
SELECT DAY,
[Week nu],
case when [Week nu]<=26 then 'First Semester' Else 'Second Semester' end Semester,
case when [Week nu]<=26 then [Week nu] Else [Week nu]-26 end[Semester Week nu]
INTO #currentDates
FROM
(SELECT DAY = DATEADD(DAY, rn - 1, #StartDate),
DATEPART(WEEK,DATEADD(DAY, rn - 1, #StartDate)) [Week nu]
FROM
(SELECT TOP (DATEDIFF(DAY, #StartDate, #CutoffDate)+1) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]) AS x) AS y;

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

Count orders by days of the week, adding Saturday & Sunday counts to Friday

I would like to get the count of ordered items from monday to sunday but adding saturday and sunday orders to fridays, so the query results would only display Orderdates (Monday to Friday)
I have this sql already that shows orders for every single day of the week:
select DATENAME(weekday,orderdate) Day,CONVERT(VARCHAR(10), orderdate, 103) orderdate,
COUNT(orderdate) Orders
from Orders_tb
where orderDate >= '2012-03-01 00:00:00.000'
and orderDate <= '2012-03-31 00:00:00.000'
group by datepart(day,orderDate),orderdate,DATENAME(weekday,orderdate)
Thanks for your input!
EDIT after clarification.
Use case to change weekend days to friday. Derived table is employed to avoid the need to replicate the same expression everywhere orderdate is needed.
select DATENAME(weekday,orderdate_trimmed) Day,
CONVERT(VARCHAR(10), orderdate_trimmed, 103) orderdate,
COUNT(orderdate_trimmed) Orders
from
(
select *,
order_date -
case DATENAME(weekday,orderdate)
when 'Saturday' then 1
when 'Sunday' then 2
else 0
end
orderdate_trimmed
from Orders_tb
) a
where orderDate >= '2012-03-01 00:00:00.000'
and orderDate <= '2012-03-31 00:00:00.000'
group by orderdate_trimmed
You might count matching days only by use of case statement:
select COUNT(orderdate) TotalOrders,
COUNT(CASE WHEN DATENAME(weekday,orderdate) = 'Monday' then 1 end) Monday,
COUNT(CASE WHEN DATENAME(weekday,orderdate) = 'Tuesday' then 1 end) Tuesday,
COUNT(CASE WHEN DATENAME(weekday,orderdate) = 'Wednesday' then 1 end) Wednesday,
COUNT(CASE WHEN DATENAME(weekday,orderdate) = 'Thursday' then 1 end) Thursday,
COUNT(CASE WHEN DATENAME(weekday,orderdate) = 'Friday'
OR DATENAME(weekday,orderdate) = 'Saturday'
OR DATENAME(weekday,orderdate) = 'Sunday'
THEN 1 end) Friday
from Orders_tb
where orderDate >= '2012-03-01 00:00:00.000'
and orderDate <= '2012-03-31 00:00:00.000'
A warning about dates: as a date can contain time portion it would be wiser to compare like this:
where orderDate >= '2012-03-01 00:00:00.000'
and orderDate < '2012-04-01 00:00:00.000'