SQL Grouping cube and pivot - sql

I'm trying to do the following query where I obtain a table grouping by years, month and sites, and then I pivot this sites to columns:
SELECT * FROM
(
SELECT
DECODE(GROUPING(TO_CHAR(TM.TIMESTAMP,'YYYY'))
,0, TO_CHAR(TM.TIMESTAMP,'YYYY')
,1, 'TOTAL') AS "YEAR",
DECODE(GROUPING(TO_CHAR(TM.TIMESTAMP,'MM'))
,0, TO_CHAR(TM.TIMESTAMP,'MM')
,1, 'TOTAL') AS "MONTH",
DECODE(GROUPING(TS.CODIGO5)
,0, TS.CODIGO5
,1, 'TOTAL') AS BU,
SUM(TM.KWHGEN) AS GEN
FROM T_MEDIDAS_CO TM
JOIN T_Sede TS ON TM.id_sede=TS.id_sede
WHERE TO_CHAR(TM.TIMESTAMP,'YYYY') IN (2015,2014)
AND TS.CODIGO5 IN ('FINSI', 'FINOC')
GROUP BY CUBE (TO_CHAR(TM.TIMESTAMP,'YYYY'), TO_CHAR(TM.TIMESTAMP,'MM'), TS.CODIGO5)
ORDER BY TO_CHAR(TM.TIMESTAMP,'YYYY') DESC, TO_CHAR(TM.TIMESTAMP,'MM') DESC, 3
)
PIVOT
(
SUM(GEN)
FOR BU IN ('FINCI' AS FINCI,'FINSI' AS FINSI, 'FINOC' AS FINOC, 'TOTAL' AS TOTAL)
)
ORDER BY "YEAR" DESC, "MONTH" DESC
to obtain this result
YEAR MONTH FINCI FINOC TOTAL
2015 12 110376,17 109991,55 220367,72
2015 11 92032,56 97938,09 189970,65
2015 10 77668,67 79273,98 156942,65
2015 09 87079,46 91203,73 178283,19
2015 08 99992,38 100220,24 200212,62
2015 07 142430 133979,74 276409,74
2015 06 107006,73 104320,96 211327,69
2015 05 86264 90985,62 177249,62
2015 04 85838,41 87147,74 172986,15
2015 03 106178,39 106342,4 212520,79
2015 02 125007,65 122790,76 247798,41
2015 01 134934,67 135897,7 270832,37
2015 TOTAL 1254809,09 1260092,51 2514901,6
2014 12 121185,25 122014,9 243200,15
2014 11 94682,9 94221,47 188904,37
2014 10 87212,59 92222,92 179435,51
2014 09 97306,19 100701,93 198008,12
2014 08 97738,26 101901,88 199640,14
2014 07 113242,07 117496,84 230738,91
2014 06 98234,69 98092,2 196326,89
2014 05 91202,74 102214,94 193417,68
2014 04 88517,65 103756,83 192274,48
2014 03 107541,53 119236,48 226778,01
2014 02 127880,75 131451,38 259332,13
2014 01 141381,35 143836,44 285217,79
2014 TOTAL 1266125,97 1327148,21 2593274,18
TOTAL 12 231561,42 232006,45 463567,87
TOTAL 11 186715,46 192159,56 378875,02
TOTAL 10 164881,26 171496,9 336378,16
TOTAL 09 184385,65 191905,66 376291,31
TOTAL 08 197730,64 202122,12 399852,76
TOTAL 07 255672,07 251476,58 507148,65
TOTAL 06 205241,42 202413,16 407654,58
TOTAL 05 177466,74 193200,56 370667,3
TOTAL 04 174356,06 190904,57 365260,63
TOTAL 03 213719,92 225578,88 439298,8
TOTAL 02 252888,4 254242,14 507130,54
TOTAL 01 276316,02 279734,14 556050,16
TOTAL TOTAL 2520935,06 2587240,72 5108175,78
But, I don't need the TOTAL | MONTH rows, how can I fix it?
Thanks a lot

Related

Create list based on actual month and year

I have my code which should returns names of the months from now and the year for the next 12 months.
e.g. whe have now September so the code should retuns list of months with year till the September 2023th.
month_names = "January February March April May June July August September October November December".split()
Year = '2022'
month_now = datetime.date.today().month
dict_of_dfs = {}
for i in range(month_now,len(month_names)):
df_name = month_names[i]
print(Year,i+1,'01')
This code returns only the months till the end of the year and I do not know how to change it.
The output should look like that:
2022 10 01
2022 11 01
2022 12 01
2023 01 01
2023 02 01
2023 03 01
...
2023 07 01
2023 08 01
2023 09 01
Check pd.date_range
pd.date_range(start = Year + '-' + str(month_now+1) + '-01', periods=12, freq='MS')
Another solution with pd.date_range:
pd.date_range(start=month_now.replace(day=1), periods=13, freq='MS')[1:]
Using Pendulum:
import pendulum
date_list = [pendulum.now().add(months=1).start_of("month").add(months=x).to_date_string() for x in range(12)]
print(date_list)
['2022-10-01', '2022-11-01', '2022-12-01', '2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01', '2023-05-01', '2023-06-01', '2023-07-01', '2023-08-01', '2023-09-01']

How to calculate median monthly from date of month table?

My dataset:
Date Num_orders
Mar 21 2019 69
Mar 22 2019 82
Mar 24 2019 312
Mar 25 2019 199
Mar 26 2019 2,629
Mar 27 2019 2,819
Mar 28 2019 3,123
Mar 29 2019 3,332
Mar 30 2019 1,863
Mar 31 2019 1,097
Apr 01 2019 1,578
Apr 02 2019 2,353
Apr 03 2019 2,768
Apr 04 2019 2,648
Apr 05 2019 3,192
Apr 06 2019 2,363
Apr 07 2019 1,578
Apr 08 2019 3,090
Apr 09 2019 3,814
Apr 10 2019 3,836
...
I need to calculate the monthly median number of orders from days of the same month:
The desired results:
Month Median_monthly
Mar 2019 1,863
Apr 2019 2,768
May 2019 2,876
Jun 2019 ...
...
I tried to use function date_trunc to extract month from the dataset then group by 'month' but it didn't work out. Thanks for your help, I use Google Bigquery (#standard) environment!
Probably you tried to use PERCENTILE_CONT which can not be used with GROUP BY:
Try to use APPROX_QUANTILES(x, 100)[OFFSET(50)]. It should work with GROUP BY.
SELECT APPROX_QUANTILES](Num_orders, 100)\[OFFSET(50)\] AS median
FROM myTable
GROUP BY Month
Alternativele you can use PERCENTILE_CONT within subquery:
SELECT
DISTINCT Month, median
FROM (
SELECT
Month,
PERCENTILE_CONT(Num_orders, 0.5) OVER(PARTITION BY Month) AS median
FROM myTable
)
This would often be done using DISTINCT:
SELECT DISTINCT DATE_TRUNC(month, date),
PERCENTILE_CONT(Num_orders, 0.5) OVER (PARTITION BY DATE_TRUNC(month, date) AS median
FROM myTable;
Note: There are two percentile functions, PERCENTILE_CONT() and PERCENTILE_DISC(). They have different results when there is a "tie" in the middle of the data.

SQL find rows in groups where a column has a null and a non-null value

The Data
row ID YEAR PROD STA DATE
01 01 2011 APPLE NEW 2011-11-18 00:00:00.000
02 01 2011 APPLE NEW 2011-11-18 00:00:00.000
03 01 2013 APPLE OLD NULL
04 01 2013 APPLE OLD NULL
05 02 2013 APPLE OLD 2014-04-08 00:00:00.000
06 02 2013 APPLE OLD 2014-04-08 00:00:00.000
07 02 2013 APPLE OLD 2014-11-17 10:50:14.113
08 02 2013 APPLE OLD 2014-11-17 10:46:04.947
09 02 2013 MELON OLD 2014-11-17 11:01:19.657
10 02 2013 MELON OLD 2014-11-17 11:19:35.547
11 02 2013 MELON OLD NULL
12 02 2013 MELON OLD 2014-11-21 10:32:36.017
13 03 2006 APPLE NEW 2007-04-11 00:00:00.000
14 03 2006 APPLE NEW 2007-04-11 00:00:00.000
15 04 2004 APPLE OTH 2004-09-27 00:00:00.000
16 04 2004 APPLE OTH NULL
ROW is not a column in the table. Is just to show which records i want.
The question
I need to find rows where a group consisting of (ID, YEAR, PROD, STA) has at least one NULL DATE and a non-NULL DATE.
Expected result
From the above dataset this would be rows 9 to 12 and 15 to 16
Im sitting in front od SSMS and have no idea how to get this. Thinking about group by and exists but really no idea.
You can use COUNT ... OVER:
SELECT ID, YEAR, PROD, STA, [DATE]
FROM (
SELECT ID, YEAR, PROD, STA, [DATE],
COUNT(IIF([DATE] IS NULL, 1, NULL)) OVER
(PARTITION BY ID, YEAR, PROD, STA) AS cnt_nulls,
COUNT(IIF([DATE] IS NOT NULL, 1, NULL)) OVER
(PARTITION BY ID, YEAR, PROD, STA) AS cnt_not_nulls
FROM mytable) AS t
WHERE t.cnt_nulls > 0 AND t.cnt_not_nulls > 0
The window version of COUNT is applied twice over ID, YEAR, PROD, STA partitions of data: it returns for every row the population of the current partition. The count is conditionally performed:
the first COUNT counts the number of NULL [Date] values within the partition
the second COUNT counts the number of NOT NULL [Date] values within the partition.
The outer query checks for partitions having a count of at least one for both of the two COUNT functions of the inner query.

Trying to pull the required rows from the single table with applying conditional statements on columns in sql server?

I have tried in n-number ways to solve this solution but unfortunately I got stuck in all the ways..
source table
id year jan feb mar apr may jun jul aug sep oct nov dec
1234 2014 05 06 12 15 16 17 18 19 20 21 22 23
1234 2013 05 06 12 15 16 17 18 19 20 21 22 23
Task: Assume that we are currently at March 2014, and we need 12 months back date ...(i.e., from Mar 2013 to Feb 2014, and the remaining values needs to be zero except year and id.)
Solution:
id year jan feb mar apr may jun jul aug sep oct nov dec
1234 2014 05 06 0 0 0 0 0 0 0 0 0 0
1234 2013 0 0 12 15 16 17 18 19 20 21 22 23
This needs a code solution for SQL Server 2008. I would be very happy if any body can solve this.
Note:
I got stuck to pull the column names dynamically.
You can try this:
select id, year, case when DATEDiff(month, getdate(), convert(datetime, year + '-01-01'))) < 12 then jan else 0,
DATEDiff(month, getdate(), convert(datetime, year + '-02-01'))) < 12 then fab else 0 ....

MDX Query with running total across crossjoined dimensions

I have a cube with the following three dimensions: Date, Time and Shift. I have a measure called [Pieces Succeeded], and I want a running total of the [Pieces Succeeded] by hour for a Shift. A Shift can span more than one day, so in the following query, I do a crossjoin of the Date and Time dimensions.
with
member [Measures].[Pieces Succeeded Running Total] as
sum([Time].[Hierarchy].[Hour].FirstMember:[Time].[Hour].CurrentMember, [Measures].[Pieces Succeeded])
select
{ [Measures].[Pieces Succeeded], [Measures].[Pieces Succeeded Running Total] } on columns,
nonempty(crossjoin([Date].[Month Hierarchy].[Day].Members, [Time].[Hierarchy].[Hour].Members)) on rows
from
[OEE]
where
[Shift].[Month Hierarchy].[Shift].&[501]
Which gives the following results:
Date Hour Pieces Succeeded Pieces Succeeded Running Total
03 Apr 2011 22 6393 6393
03 Apr 2011 23 6424 12817
04 Apr 2011 00 3816 3816
04 Apr 2011 01 5510 9326
04 Apr 2011 02 2090 11416
04 Apr 2011 03 7489 18905
04 Apr 2011 04 7307 26212
04 Apr 2011 05 5706 31918
How would I go about getting the sum to work on the crossjoined set so that the Running Total works across days?
Thanks
I spent all day on this, and finally figured it out. I thought it might be valuable for someone else, so here's the solution:
with
set DateHours as
nonempty(crossjoin([Date].[Month Hierarchy].[Day].Members, [Time].[Hierarchy].[Hour].Members), [Measures].[Pieces Succeeded])
member [Measures].[Rank] as
rank(([Date].[Month Hierarchy].CurrentMember, [Time].[Hierarchy].CurrentMember ), DateHours)
member [Measures].[Running Pieces Succeeded] as
iif([Measures].[Rank] = 1, [Measures].[Pieces Succeeded], sum(head(DateHours, [Measures].[rank]), [Measures].[Pieces Succeeded]))
select
{ [Measures].[Pieces Succeeded], [Measures].[Running Pieces Succeeded] } on columns,
non empty { DateHours } on rows
from
[OEE]
where
[Shift].[Month Hierarchy].[Shift].&[501]