BigQuery: How to convert Year to Decade? - google-bigquery

In this great article, I found the way to convert Year into Decade, but it looks too verbose to me!
Is there better way to do this?
#standardSQL
WITH data AS (
SELECT '1921' AS YEAR UNION ALL
SELECT '1932' UNION ALL
SELECT '1943' UNION ALL
SELECT '1954' UNION ALL
SELECT '1985' UNION ALL
SELECT '2006' UNION ALL
SELECT '2017' UNION ALL
SELECT '2018'
)
SELECT
YEAR,
CASE
WHEN YEAR LIKE "192%" THEN "20S"
WHEN YEAR LIKE "193%" THEN "30S"
WHEN YEAR LIKE "194%" THEN "40S"
WHEN YEAR LIKE "195%" THEN "50S"
WHEN YEAR LIKE "196%" THEN "60S"
WHEN YEAR LIKE "197%" THEN "70S"
WHEN YEAR LIKE "198%" THEN "80S"
WHEN YEAR LIKE "199%" THEN "90S"
WHEN YEAR LIKE "200%" THEN "2000S"
WHEN YEAR LIKE "201%" THEN "2010S"
END AS DECADES
FROM data
-- ORDER BY YEAR

To "extract" Decade from Year - REGEXP_REPLACE function can be used as in example below
#standardSQL
WITH data AS (
SELECT '1921' AS YEAR UNION ALL
SELECT '1932' UNION ALL
SELECT '1943' UNION ALL
SELECT '1954' UNION ALL
SELECT '1985' UNION ALL
SELECT '2006' UNION ALL
SELECT '2017' UNION ALL
SELECT '2028'
)
SELECT
YEAR,
REGEXP_REPLACE(YEAR, r'(?:19)(\d)\d|(20\d)\d', '\\1\\20s') AS DECADES
FROM data
-- ORDER BY YEAR

Related

How can I use the LAG FUNCTION to show revenue this year vs last year in Snowflake with?

I would like to show the current revenue vs last's year's revenue in the same row per region per type. Example:For 2022-04-01, US, Type 1 --> REVENUE: 2456, REVENUE_LAST_YEAR: 4000
2021-04-01, US, Type 1 --> REVENUE: 4000, REVENUE_LAST_YEAR: 0
For some reason, the Lag formula in Snowflake is showing wrong values. Could someone please help ?
WITH
indata(dt,region,type,revenue) AS (
SELECT DATE '2021-04-01','US','Type 1',4000 UNION ALL SELECT DATE '2021-05-01','Europe','Type 2',5777
UNION ALL SELECT DATE '2021-06-01','US','Type 1',45433 UNION ALL SELECT DATE '2021-07-01','Europe','Type 2',8955
UNION ALL SELECT DATE '2021-08-01','US','Type 1',45777 UNION ALL SELECT DATE '2021-09-01','Asia','Type 1',7533
UNION ALL SELECT DATE '2021-10-01','US','Type 1',8866 UNION ALL SELECT DATE '2021-11-01','Asia','Type 2',5534
UNION ALL SELECT DATE '2021-12-01','US','Type 2',4000 UNION ALL SELECT DATE '2022-01-01','Asia','Type 1',7244
UNION ALL SELECT DATE '2022-02-01','US','Type 1',6678 UNION ALL SELECT DATE '2022-03-01','Asia','Type 1',5654
UNION ALL SELECT DATE '2022-04-01','US','Type 1',2456 UNION ALL SELECT DATE '2022-05-01','Asia','Type 1',4525
UNION ALL SELECT DATE '2022-06-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-07-01','Asia','Type 1',6654
UNION ALL SELECT DATE '2022-08-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-09-01','Asia','Type 2',5754
UNION ALL SELECT DATE '2022-10-01','US','Type 1',7744 UNION ALL SELECT DATE '2022-11-01','Asia','Type 2',5644
UNION ALL SELECT DATE '2022-12-01','Europe','Type 2',6775 UNION ALL SELECT DATE '2023-01-01','Asia','Type 2',6777
UNION ALL SELECT DATE '2023-02-01','Europe','Type 2',7755
)
SELECT indata.*,
lag(REVENUE, 1, 0) over (partition by region,type,revenue order by year(dt)) REVENUE_last_year
FROM indata
order by year(dt)
Partitioning by region, type and month-day:
SELECT indata.*,
LAG(REVENUE, 1, 0) over (partition by region,type, TO_VARCHAR(dt, 'mmdd')
order by dt) AS REVENUE_last_year
FROM indata
ORDER BY dt;
Output:

Rolling sum previous 12 months grouped by 2 dimensions (SQL- Snowflake)

I have the following table structure available in the C:
I am struggling in Snowflake with a query that should show me the the sum of previous 12 months for every distinct month in the table split into three dimensions .
The way reporting date 01.08.2022 for region='US' and type=1 is calculated: it is the sum of the past 12 months' row of "revenue_12_months" = 4000+ 45433+45777+ 8866+ 4000+ 6678+ 2456+ 6677+ 6677+ 7744+ 6775 + 7755
WITH
indata(dt,region,type,revenue) AS (
SELECT DATE '2021-04-01','US','Type 1',4000 UNION ALL SELECT DATE '2021-05-01','Europe','Type 2',5777
UNION ALL SELECT DATE '2021-05-01','US','Type 1',45433 UNION ALL SELECT DATE '2021-07-01','Europe','Type 2',8955
UNION ALL SELECT DATE '2021-06-01','US','Type 1',45777 UNION ALL SELECT DATE '2021-09-01','Asia','Type 1',7533
UNION ALL SELECT DATE '2021-07-01','US','Type 1',8866 UNION ALL SELECT DATE '2021-11-01','Asia','Type 2',5534
UNION ALL SELECT DATE '2021-08-01','US','Type 1',4000 UNION ALL SELECT DATE '2022-01-01','Asia','Type 1',7244
UNION ALL SELECT DATE '2021-09-01','US','Type 1',6678 UNION ALL SELECT DATE '2022-03-01','Asia','Type 1',5654
UNION ALL SELECT DATE '2021-10-01','US','Type 1',2456 UNION ALL SELECT DATE '2022-05-01','Asia','Type 1',4525
UNION ALL SELECT DATE '2021-11-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-07-01','Asia','Type 1',6654
UNION ALL SELECT DATE '2021-12-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-09-01','Asia','Type 2',5754
UNION ALL SELECT DATE '2022-01-01','US','Type 1',7744 UNION ALL SELECT DATE '2022-11-01','Asia','Type 2',5644
UNION ALL SELECT DATE '2022-02-01','US','Type 1',6775 UNION ALL SELECT DATE '2023-01-01','Asia','Type 2',6777
UNION ALL SELECT DATE '2022-03-01','US','Type 1',7755
)
select dt,region,type, SUM(revenue) OVER (ORDER BY dt,region,type ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) revenue_12_months
from indata
You want it per region and type, so that needs to part of the partition by clause
sum(revenue) over (partition by region, type order by dt rows between 11 preceding and current row)
could it be that you simply forgot the GROUP BY part in your window function?
WITH
indata(dt,region,type,revenue) AS (
SELECT DATE '2021-04-01','US','Type 1',4000 UNION ALL SELECT DATE '2021-05-01','Europe','Type 2',5777
UNION ALL SELECT DATE '2021-05-01','US','Type 1',45433 UNION ALL SELECT DATE '2021-07-01','Europe','Type 2',8955
UNION ALL SELECT DATE '2021-06-01','US','Type 1',45777 UNION ALL SELECT DATE '2021-09-01','Asia','Type 1',7533
UNION ALL SELECT DATE '2021-07-01','US','Type 1',8866 UNION ALL SELECT DATE '2021-11-01','Asia','Type 2',5534
UNION ALL SELECT DATE '2021-08-01','US','Type 1',4000 UNION ALL SELECT DATE '2022-01-01','Asia','Type 1',7244
UNION ALL SELECT DATE '2021-09-01','US','Type 1',6678 UNION ALL SELECT DATE '2022-03-01','Asia','Type 1',5654
UNION ALL SELECT DATE '2021-10-01','US','Type 1',2456 UNION ALL SELECT DATE '2022-05-01','Asia','Type 1',4525
UNION ALL SELECT DATE '2021-11-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-07-01','Asia','Type 1',6654
UNION ALL SELECT DATE '2021-12-01','US','Type 1',6677 UNION ALL SELECT DATE '2022-09-01','Asia','Type 2',5754
UNION ALL SELECT DATE '2022-01-01','US','Type 1',7744 UNION ALL SELECT DATE '2022-11-01','Asia','Type 2',5644
UNION ALL SELECT DATE '2022-02-01','US','Type 1',6775 UNION ALL SELECT DATE '2023-01-01','Asia','Type 2',6777
UNION ALL SELECT DATE '2022-03-01','US','Type 1',7755
)
select dt,region,type, SUM(revenue) OVER (PARTITION BY region, type ORDER BY dt,region,type ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) revenue_12_months
from indata
ORDER BY REGION, TYPE, DT;
Best regards,
TK

SQL: Dynamic Date creation issue

Need Suggestion to make it dynamic On Dates.
Expected:
Date, Total Sellers, Sellers From Previous Date
Currently:
Data in table(active_seller_codes): date, seller_code
Queries:
-- Date Wise Sellers Count
select date,count(distinct seller_code) as Sellers_COunt
from active_seller_codes where date between '2016-12-15' AND '2016-12-15'
-- Sellers from previous Days
select date,count(distinct seller_code) as Last_Day_Seller
from active_seller_codes
where date between '2016-12-15' AND '2016-12-15'
and seller_code IN(
select seller_code from active_seller_codes
where date between '2016-12-14' AND '2016-12-14'
)
group by 1
Database Using: Vertica
Reading attentively, you seem to want one row in the report, with the data from the search date in the first two columns and the data of the day before the search date in the third and fourth column, like so:
sales_date|sellers_count|prev_date |prev_sellers_count
2016-12-15| 8|2016-12-14| 5
The solution could be something like this (without the first Common Table Expression, which, in my case, contains the data, but in your case, the data would be in your active_seller_codes table.
WITH
-- initial input
(sales_date,seller_code) AS (
SELECT DATE '2016-12-15',42
UNION ALL SELECT DATE '2016-12-15',43
UNION ALL SELECT DATE '2016-12-15',44
UNION ALL SELECT DATE '2016-12-15',45
UNION ALL SELECT DATE '2016-12-15',46
UNION ALL SELECT DATE '2016-12-15',47
UNION ALL SELECT DATE '2016-12-15',48
UNION ALL SELECT DATE '2016-12-15',49
UNION ALL SELECT DATE '2016-12-14',42
UNION ALL SELECT DATE '2016-12-14',44
UNION ALL SELECT DATE '2016-12-14',46
UNION ALL SELECT DATE '2016-12-14',48
UNION ALL SELECT DATE '2016-12-14',50
UNION ALL SELECT DATE '2016-12-13',42
UNION ALL SELECT DATE '2016-12-13',43
UNION ALL SELECT DATE '2016-12-13',44
UNION ALL SELECT DATE '2016-12-13',45
UNION ALL SELECT DATE '2016-12-13',46
UNION ALL SELECT DATE '2016-12-13',47
UNION ALL SELECT DATE '2016-12-13',48
UNION ALL SELECT DATE '2016-12-13',49
)
,
-- search argument this, in the real query, would come just after the WITH keyword
-- as the above would be the source table
search_dt(search_dt) AS (SELECT DATE '2016-12-15')
,
-- the two days we're interested in, de-duped
distinct_two_days AS (
SELECT DISTINCT
sales_date
, seller_code
FROM active_seller_codes
WHERE sales_date IN (
SELECT search_dt FROM search_dt -- the search date
UNION ALL SELECT search_dt - 1 FROM search_dt -- the day before
)
)
,
-- the two days we want one above the other,
-- with index for the final pivot
vertical AS (
SELECT
ROW_NUMBER() OVER (ORDER BY sales_date DESC) AS idx
, sales_date
, count(DISTINCT seller_code) AS seller_count
FROM distinct_two_days
GROUP BY 2
)
SELECT
MAX(CASE idx WHEN 1 THEN sales_date END) AS sales_date
, SUM(CASE idx WHEN 1 THEN seller_count END) AS sellers_count
, MAX(CASE idx WHEN 2 THEN sales_date END) AS prev_date
, SUM(CASE idx WHEN 2 THEN seller_count END) AS prev_sellers_count
FROM vertical
;
sales_date|sellers_count|prev_date |prev_sellers_count
2016-12-15| 8|2016-12-14| 5

How to combine two queries

I have two queries
1)
select Year , Month, Sum(Stores) from ABC ;
2)
select Year, Month , Sum(SalesStores) from DEF ;
I want a result like :
**Year, Month , Sum(Stores), Sum(SalesStores)**
How can I do it ?
I tried union & Union all
select Year , Month, Sum(Stores) from ABC union
select Year, Month , Sum(SalesStores) from DEF ;
I see only 3 columns in the output
Year, Month Sum(Stores).
Here are the tables :
Year, Month Stores
Year Month SalesStores
Is there a way I can see the result in the format I would like to see ?
Since I don't know their relationship, I prefer to use UNION ALL.
SELECT Year,
Month,
MAX(TotalStores) TotalStores,
MAX(TotalSalesStores) TotalSalesStores
FROM
(
SELECT Year, Month,
SUM(Stores) TotalStores,
NULL TotalSalesStores
FROM ABC
UNION ALL
SELECT Year, Month,
NULL TotalStores,
SUM(SalesStores) TotalSalesStores
from DEF
) a
GROUP BY Year, Month
You can UNION them in the following fashion:
SELECT Year , Month, Sum(Stores) As Stores, NULL As SalesStores from ABC
UNION
SELECT Year , Month, NULL As Stores, Sum(Stores) As SalesStores from ABC
Or use UNION ALL if your logic allows it.
Try:
SELECT Year, Month, SUM(TotalStores) as TotalAllStores, SUM(TotalSalesStore) as TotalAllSalesStore
FROM
(
SELECT Year , Month, Sum(Stores) as TotalStores, 0 as TotalSalesStore from ABC union
UNION ALL
SELECT Year, Month , 0 as TotalStores, Sum(SalesStores) as TotalSalesStore from DEF
) SalesByYearMonth
GROUP BY Year, Month
I would use FULL OUTER JOIN thus:
SELECT ISNULL(x.[Year], y.[Year]) AS [Year],
ISNULL(x.[Month], y.[Month]) AS [Month],
x.Sum_Stores,
y.Sum_SalesStores
FROM (select Year , Month, Sum(Stores) AS Sum_Stores from ABC ...) AS x
FULL OUTER JOIN (select Year, Month , Sum(SalesStores) AS Sum_SalesStores from DEF ...) AS y
ON x.[Year] = y.[Year] AND x.[Month] = y.[Month]

Multiple SELECT in oracle

I want to get a particular value from 3 different tables. Each table has the same structure but contains data for a different period of a year.
Temp_Table_Jun (Contains data for June month)
---------------
CustNo CustName Revenue
1000 John 5.55
Similary I have two more tables
Temp_table_Apr
Temp_table_May
Now I run a query
select sum(Revenue)Rev_June from Temp_Table_Jun where CustNo='1000'
to get the results for June. Now my problem is I want to get the revenue details for all the month in a single query.
I need something like,(THIS IS WRONG AND DOESN'T WORK)
select Rev_June,Rev_Apr,Rev_May,((Rev_June+Rev_Apr+Rev_May)/3)Avg_3_Mon from
(
select sum(Revenue)Rev_June from Temp_Table_Jun where CustNo='1000',
select sum(Revenue)Rev_Apr from Temp_Table_Apr where CustNo='1000',
select sum(Revenue)Rev_May from Temp_Table_May where CustNo='1000'
)
How can this be achieved? I am using Oracle 10g.
To get the data you can do it the following way. Oracle 10g does not have a PIVOT but you can use CASE statements to replicate the functionality:
SELECT sum(case when month = 'June' then Rev END) June
, sum(case when month = 'May' then Rev END) May
, sum(case when month = 'April' then Rev END) April
, avg(Rev) as Average
FROM
(
SELECT sum(revenue) Rev, 'June' as Month from rev_june where cust_no = '1000'
union all
SELECT sum(revenue) Rev, 'April' from rev_apr where cust_no = '1000'
union all
SELECT sum(revenue) Rev, 'May' from rev_may where cust_no = '1000'
) x
See SQL Fiddle with Demo
Or you can do the following:
SELECT June, April, May, (June + April + May)/3 as Average
FROM
(
select
(SELECT sum(revenue) from rev_june where cust_no = '1000') as June
, (SELECT sum(revenue) from rev_apr where cust_no = '1000') as April
, (SELECT sum(revenue) from rev_may where cust_no = '1000') as May
from dual
) x
See SQL Fiddle with Demo
The following might work:
select Rev_June, Rev_Apr, Rev_May,
(Rev_June + Rev_Apr + Rev_May) / 3 Avg_3_Mon
from (
(select sum(Revenue) from Temp_Table_Jun where CustNo='1000') as Rev_June,
(select sum(Revenue) from Temp_Table_Apr where CustNo='1000') as Rev_Apr,
(select sum(Revenue) from Temp_Table_May where CustNo='1000') as Rev_May
from dual
)
I don't know if it works in Oracle 10g, but a UNION query roughly like the following would normally work in databases I've worked with:
select sum(Revenue) Rev_June from Temp_Table_Jun where CustNo='1000'
UNION
select sum(Revenue) Rev_Apr from Temp_Table_Apr where CustNo='1000'
UNION
select sum(Revenue) Rev_May from Temp_Table_May where CustNo='1000'
I'm not crysal clear about punctuation - do you need a semi-colon at the end etc? - but that might get you started.
I think I would do it slightly differently because each query must have the same structure for a UNION query to work:
select sum(Revenue) Revenue_Sum, 'Jun' Month from Temp_Table_Jun where CustNo='1000'
UNION
select sum(Revenue) Revenue_Sum, 'Apr' Month from Temp_Table_Apr where CustNo='1000'
UNION
select sum(Revenue) Revenue_Sum, 'May' Month from Temp_Table_May where CustNo='1000'
Now, that doesn't quite get the average sum and the 3 columns you're looking for, but perhaps you could create a VIEW with something like this UNION query and then use a GROUP BY query on that VIEW to aggregate the data.