SUM subcategory into one - sql

I am looking at add a date range to the below query. Any help would be fantastic thank you in advance.
select (case when col2 in ('Commercial', 'Non-commercial') then 'Commercial'
when col2 in ('OEM', 'CA-OEM') then 'OEM'
else 'col2'
end),
sum(col4) as col4
from t
group by (case when col2 in ('Commercial', 'Non-commercial') then 'Commercial'
when col2 in ('OEM', 'CA-OEM') then 'OEM'
else 'col2'
end);
The date is shown as below in SQL
SELECT Customer_type,TRX_DATE (FORMAT 'YYYY-MM') (CHAR(7)) AS BATCH_DATE_MONTH
WHERE CAST(TRX_DATE AS DATE FORMAT 'mm/dd/yyyy') >= '02-01-2016'
Group BY 1,2
ORDER BY 1
Customer_Type BATCH_DATE_MONTH Number_Invoices Billed_Amount
1 Commercial-Non-OEM 2016-02 48 382458.92
2 Commercial- Non-OEM 2016-05 77 7646263.67
5 Non-OEM 2016-05 81 11841927.23
6 Non-OEM 2016-02 25 1630832.81
9 OEM 2016-04 68 280264011.01
10 OEM 2016-03 74 277606302.23
13 CA-OEM 2016-03 23 947248.13
14 CA-OEM 2016-05 17 420363.61
17 US-OEM 2016-04 35 4627887.87
18 US-OEM 2016-03 40 6450226.49
19 US-OEM 2016-02 21 3267732.17

You can use an aggregation query with case:
select (case when col2 in ('Commercial', 'Non-commercial') then 'Commercial'
when col2 in ('OEM', 'CA-OEM') then 'OEM'
else 'col2'
end),
sum(col4) as col4
from t
group by (case when col2 in ('Commercial', 'Non-commercial') then 'Commercial'
when col2 in ('OEM', 'CA-OEM') then 'OEM'
else 'col2'
end);

Related

SQL query to calculate a value from 3 different rows

col1 col2 cal_val
F 1879 1879
% 25 1409
$ -45 1454
First row basically outputs back the entry in column 2
2nd row would basically calculate 25% of the value in row1, column 3 and then subtract that value from previous value which is 1879-470 = 1409
I need to be able to calculate final value of 1454 (which is basically a subtraction from the 2nd row output value)1409 - (-45) which would equal to 1454
You can use conditional aggregation:
select ( (sum(case when col1 = 'F' then col2 end) *
sum(case when col1 = '%' then 1 - col2 / 100.0 end)
) -
sum(case when col1 = '$' then col2 end)
)
from t;
Here is a db<>fiddle.
create temporary table t_teble
(
col1 text ,
col2 numeric ,
cal_val numeric );
insert into t_teble
select 'F',1879, 1879 union all
select '%',25,1409 union all
select '$',-45,1454;
select ( (sum(case when col1 = 'F' then col2 end) *
sum(case when col1 = '%' then 1 - col2 / 100.0 end)
) -
sum(case when col1 = '$' then col2 end)
),
(sum(case when col1 = 'F' then col2 end) *
sum(case when col1 = '%' then 1 - col2 / 100.0 end)
)
from t_teble;

SQL : MAX() OVER (PRITITON BY ... ORDER BY ..) : ORDER BY Clause is working looks like

I am trying to use MAX(case when col4='ABC' then col1 else 0 end) OVER (PARTITION BY col2 order by **col3**)
col1~col2~col3~col4
30 A B1 ABC
35 A A1 ABC
36 A NULL NULL
40 A X1 ABC
50 B M1 ABD
but I am getting the result as 40, but I want 35 as my result. It looks like
order by col3
is not getting applied before MAX aggregate. Is there any other way?
I can't write the row_number() in where clause, as we are trying to create columns and there are many columns and complicated logic around it.
Currently I am trying it in Teradata, but actually it will be implemented in HIVE.
This is too long for a comment. For this expression:
MAX(case when col4 = 'ABC' then col1 else 0 end) OVER (PARTITION BY col2 order by col3)
You should be getting:
col1~col2~col3~col4
30 A A1 ABC 30
40 A X1 ABC 40
50 B M1 ABD 0
If you want "30" for all, you might consider:
min(case when col4 = 'ABC' then col1 end) over ()
PARTITION BY will aggregate on distinct col2 values. Therefore, the MAX() value of the three col2 'A' values is 40.
If you want to return '35'. This is suggesting that A1 is the first row returned in the partition. First_Value() could be used to return the first row in the partition group.
FIRST_VALUE(CASE WHEN col4 = 'ABC' THEN col1
ELSE 0 END) OVER (PARTITION BY col2 order by col3)
EDIT: Have moved to window function in sub query to get correct row
Sample data (as table variable)
declare #t table(col1 int,col2 char(1),col3 char(2),col4 char(3))
insert #t values (30,'A','B1','ABC')
,(35,'A','A1','ABC')
,(36,'A',NULL,NULL)
,(40,'A','X1','ABC')
,(50,'B','M1','ABD')
Query using row_number() to get row to join to
select t.*, mx
from #t t
join (
select
col2,
case when col4='ABC' then col1 else 0 end as mx,
row_number() over (PARTITION BY col2 order by case when col3 is null then 1 else 0 end, col3) rn
from #t
) m on m.col2=t.col2 and rn=1
Result:
col1 col2 col3 col4 col2 mx
30 A B1 ABC A 35
35 A A1 ABC A 35
36 A NULL NULL A 35
40 A X1 ABC A 35
50 B M1 ABD B 0

How to get number of false in every column of a table?

I have a table say T_myTable it has 5 columns and all have some values either true or false.
--------------------------------
col1 | col2 | col3 | col4 | col5
--------------------------------
true | false|false|true |false
false| true |false|false|false
true | false|false|true |false
false| false|false|true |false
I want to get result as:-
col1 | col2 | col3 | col4 | col5
--------------------------------
2 | 3 |4 |1 |4
Where these numbers here are numbers of false.
Also true and false are varchar.
This:
SELECT SUM(CASE WHEN Col1 = 'false' THEN 1 ELSE 0 END) AS Col1
, SUM(CASE WHEN Col2 = 'false' THEN 1 ELSE 0 END) AS Col2
, SUM(CASE WHEN Col3 = 'false' THEN 1 ELSE 0 END) AS Col3
, SUM(CASE WHEN Col4 = 'false' THEN 1 ELSE 0 END) AS Col4
, SUM(CASE WHEN Col5 = 'false' THEN 1 ELSE 0 END) AS Col5
FROM T_myTable
Try this:
SELECT SUM(CASE col1 WHEN 'false' THEN 1 ELSE 0 END),
SUM(CASE col2 WHEN 'false' THEN 1 ELSE 0 END),
SUM(CASE col3 WHEN 'false' THEN 1 ELSE 0 END),
SUM(CASE col4 WHEN 'false' THEN 1 ELSE 0 END),
SUM(CASE col5 WHEN 'false' THEN 1 ELSE 0 END)
FROM T_myTable
One of the most interesting way is to:
unpivot data to be able to filter data
pivot data again to get count of 'false'
Check this:
SELECT [col1],[col2],[col3],[col4],[col5]
FROM (
SELECT MyVal, ColName
FROM (
SELECT *
FROM T_myTable
) AS pvt
UNPIVOT(MyVal FOR ColName IN ([col1],[col2],[col3],[col4],[col5])) AS unpvt
WHERE MyVAl = 'false'
) As DT
PIVOT (COUNT(MyVal) FOR ColName IN ([col1],[col2],[col3],[col4],[col5])) AS PT
Result:
col1 col2 col3 col4 col5
2 3 4 1 4

SQL GROUP BY with a SUM CASE statement

I know that there are a lot of question like this:
SQL GROUP BY CASE statement with aggregate function
but I've tried doing:
with T as (select col1 , SUM(CASE WHEN col2 = 1 THEN col3 ELSE 0 END) AS Totale
from tabella
group by col1, col2)
select col1, Totale
from T
group by col1, Totale
but I'm getting
col1 | Totale
---------------
1 0
1 70
2 0
2 90
Instead of:
col1 | Totale
---------------
1 70
2 90
What's wrong with that?
UPDATE:
My bad, I try to keep it simple but I've overdone it.. What I've to do is:
with T as (select col1 , SUM(CASE WHEN col2 = 1 THEN col3 ELSE 0 END) AS TotaleA,
SUM(CASE WHEN col2 = 2 THEN col3 ELSE 0 END) AS TotaleB,
(...)
from tabella
group by col1, col2)
select col1, TotaleA, TotaleB
from T
group by col1, TotaleA, TotaleB
And the solution is to do without col2 in the grouping... I was afraid getting "invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause", but it's not.. Can I mark a comment as the correct answer?
You can also approach this problem by using a subquery:
SELECT
col1,
SUM(A) TotalA,
SUM(B) TotalB
FROM
(
select col1,
CASE WHEN col2 = 1 THEN col3 ELSE 0 END A,
CASE WHEN col2 = 2 THEN col3 ELSE 0 END B
from tabella
) t
GROUP BY Col1
Here is one idea. Not sure why you have this wrapped in a cte but why not make it simpler?
select col1
, SUM(col3) AS Totale
from tabella
where col2 = 1
group by col1

staircase behavior with pivoted data

Hail to the fellow programmers and query writers,
I have this beautiful query
SELECT ID, [1] AS coL1, [15] AS coL2, [2] AS coL3, [16] AS coL4, [12] AS coL5
FROM MY_TABLE
PIVOT (sum(INT_VALUE) FOR FUND_CODE IN ([1],[2],[15],[16],[12])) AS p
--GROUP BY ID, [1] , [15] , [2] , [16] , [12]
ORDER BY ID ASC
That returns me data like this:
10001 182 NULL NULL NULL
10001 NULL 81 NULL NULL
10001 NULL NULL 182 NULL
10001 NULL NULL NULL 81
10002 165 NULL NULL NULL
10002 NULL 73 NULL NULL
10002 NULL NULL 165 NULL
10002 NULL NULL NULL 73
The 10001 and 10002 are two primary keys, and I'd like to show my data like this:
10001 182 81 182 81
10002 165 73 165 73
I tried this commented GROUP BY to no avail.
Any hints? Does it involve COALESCE?
SELECT ID
,SUM(1) AS 'col1'
,SUM(15) AS 'col2'
,SUM(2) AS 'col3'
,SUM(16) AS 'col4'
,SUM(12) AS 'col5'
FROM Table GROUP BY ID
Just in CASE...
SELECT ID,
SUM(CASE WHEN FUND_CODE = 1 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL1,
SUM(CASE WHEN FUND_CODE = 15 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL2,
SUM(CASE WHEN FUND_CODE = 2 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL3,
SUM(CASE WHEN FUND_CODE = 16 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL4,
SUM(CASE WHEN FUND_CODE = 12 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL5
FROM MY_TABLE
GROUP BY ID