SQL pivot to arrange data to 12 months output - sql

I have a Table named: ListOfdates
TYPE | O_DATE | C_DATE |
+------+-------------+---------------+
A 15-JAN-2017 (NULL)
A 15-JAN-2017 (NULL)
A 15-JAN-2017 25-APR-2017
A 15-JAN-2017 (NULL)
A 24-FEB-2017 (NULL)
A 15-MAY-2017 (NULL)
B 15-MAY-2017 25-MAY-2017
C 15-MAY-2017 (NULL)
D 15-MAY-2017 26-MAY-2017
A 15-MAY-2017 (NULL)`
I want to arrange it into the below,
`MONTH | Type A |Total| Type B |Total| Type C |Total| Type D |Total|
| A_o | A_c | T_o | B_o | B_c | T_o | C_o | C_c | T_o | D_o | D_c | T_o |
JAN | 4 | 0 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
FEB | 1 | 0 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
MAR | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
APR | 0 | 1 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
MAY | 2 | 0 | 6 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
JUN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
...`
The conditions are,
o_date will add a count to open for the month and type.
If c_date is not null, it will add a count to the close for the month and type
else if it is null for the c_date, there won't be a count to the close.
also, there will be a total count for the number of open for each type accumulated from the start of the year.
All 12 months must be displayed.
The acronym are:
`O_DATE = open date
C_DATE = close date
A_o = Type A open
A_c = Type A close
B_o = Type A open
B_c = Type B close
C_o = Type C open
T_o = Total open for the type (example may have 2 type A that is open)
etc...`
Is there a way to do it in sql with pivot?

I would do this using conditional aggregation, but first you have to unpivot the data:
select to_char(dte, 'MON'),
sum(case when type = 'A' then open else 0 end) as A_o,
sum(case when type = 'A' then close else 0 end) as A_c,
sum(case when type = 'A' then 1 else 0 end) as A_total,
. . .
from ((select type, o_date as dte, 1 as open, 0 as close from t) union al
(select type, c_date as dte, 0 as open, 1 as close from t)
) oc
group by to_char(dte, 'MON')
order by min(dte);

Related

Oracle Condition to Only Pull '0' Values

I need to pull ID's with only 0 values for both A and B columns. An example:
+----+------+------+
| ID | A | B |
+----+------+------+
| 1 | null | 123 |
| 2 | 23 | 768 |
| 3 | 0 | 0 |
| 4 | 96 | 0 |
| 5 | 0 | null |
| 6 | 0 | 0 |
+----+------+------+
I have tried several queries, but I am still pulling through values above 0. As there are null values in the table, I have used the NVL(expr1,0) syntax to replace null with 0:
+----+------+------+
| ID | A | B |
+----+------+------+
| 1 | 0 | 123 |
| 2 | 23 | 768 |
| 3 | 0 | 0 |
| 4 | 96 | 0 |
| 5 | 0 | 0 |
| 6 | 0 | 0 |
+----+------+------+
I am using the following in my WHERE clause, and get the below results:
Where status = 'OPEN'
AND a.value IS NULL OR a.value = '0'
AND b.value IS NULL OR b.value = '0'
Output:
+----+----+-----+
| ID | A | B |
+----+----+-----+
| 1 | 0 | 123 |
| 3 | 0 | 0 |
| 5 | 0 | 0 |
| 6 | 0 | 0 |
+----+----+-----+
It seems as though I am pulling only 0 values for A, but I am still getting values above 0 for B. I need to only pull ID's with a value of 0 for both A and B.
I think you just need parentheses:
Where status = 'OPEN' AND
(a.value IS NULL OR a.value = 0) AND
(b.value IS NULL OR b.value = 0)
I like Gordon's answer, but I would use COALESCE here for brevity:
SELECT *
...
WHERE
status = 'OPEN' AND
COALESCE(a.value, 0) = 0 AND
COALESCE(b.value, 0) = 0;
We could also express using a sum:
WHERE
status = 'OPEN' AND
COALESCE(a.value, 0) + COALESCE(b.value, 0) = 0;

How to set value based on value existence in SQL Server?

I have the following T-SQL code:
select
id,
(case
when n in(Bla1', 'Bla2') then 1
when n = 'Bla3' then 99
else 0
end) as c
from
hello
Running this code outputs this result:
| id | c |
+--------+----+
| 577140 | 0 |
| 577140 | 1 |
| 577140 | 0 |
| 577140 | 0 |
| 577140 | 99 |
| 577141 | 0 |
| 577141 | 0 |
| 577141 | 0 |
| 577142 | 0 |
| 577142 | 0 |
| 577142 | 1 |
How can I modify the code to get the following output?
| id | c |
+--------+----+
| 577140 | 99 |
| 577141 | 0 |
| 577142 | 1 |
Rule
For each id: If 99 exists, then c becomes 99. If not, either 1 or 0, depending if any 1 exists.
You can use aggregation:
select id,
max(case when n in ('Bla1', 'Bla2') then 1
when n = 'Bla3' then 99
else 0
end) as c
from hello
group by id;

sql number login and create sql query

i have below data
Column
1
0
1
0
1
0
1
1
0
1
1
0
0
0
i need o/p below
1
1
1
0
0
1
1
0
0
1
0
In SQL Server, you can do something like this...
SELECT IIF(id = 0, 1, 0) AS col1
FROM (SELECT id,
Row_number() OVER( ORDER BY (SELECT NULL)) AS rn
FROM tablename) tmp
ORDER BY rn DESC
Result
+------+
| col1 |
+------+
| 1 |
| 1 |
| 1 |
| 0 |
| 0 |
| 1 |
| 0 |
| 0 |
| 1 |
| 0 |
| 1 |
| 0 |
| 1 |
| 0 |
+------+

Summing Counts into Multiple New Columns Grouped By Another Column

I am trying to subtract two columns and then count how many have the same difference and put those sums into columns. The sums are of how many have a difference of -3 or more, -2, -1, 0, 1, 2, 3 or more grouped by date.
Query must be executed against a DB2 database.
Data...
------------------------------
| Date | Num 1 | Num 2 |
------------------------------
| 2014-02-11 | 19872 | 19873 |
| 2014-02-11 | 19873 | 19873 |
| 2014-02-12 | 19875 | 19873 |
| 2014-02-13 | 19870 | 19873 |
| 2014-02-13 | 19872 | 19873 |
| 2014-02-14 | 19877 | 19869 |
| 2014-02-14 | 19873 | 19873 |
Desired Output...
-----------------------------------------------------------------------
| Date | <= -3 | -2 | -1 | 0 | +1 | +2 | >= +3 |
-----------------------------------------------------------------------
| 2014-02-11 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 2014-02-12 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2014-02-13 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| 2014-02-14 | 1 | 0 | 0 | 1 | 9 | 0 | 0 |
Try this:
select Date,
sum(case when diff <= -3 then 1 else 0 ) AS [<=-3],
sum(case when diff = -2 then 1 else 0 ) AS [-2],
sum(case when diff = -1 then 1 else 0 ) AS [-1],
sum(case when diff = 0 then 1 else 0 ) AS [0],
sum(case when diff = 1 then 1 else 0 ) AS [+1],
sum(case when diff = 2 then 1 else 0 ) AS [+2],
sum(case when diff >= 3 then 1 else 0 ) AS [>=+3]
from
(select Date, Num1, Num2, (Num1-Num2) diff from TableA)TableB
group by Date

SSRS Remove Column from Report

i am including column 13 as a dummy column here:
+----+---+---+---+----+---+---+---+---+---+----+----+----+----+
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
+----+---+---+---+----+---+---+---+---+---+----+----+----+----+
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 2 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 4 | 1 | 0 | 0 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
+----+---+---+---+----+---+---+---+---+---+----+----+----+----+
the reason i am including a dummy column is so that IF columns 1 through 12 are all zero, i would still like to include an entry for that row.
as you can see row 1 would not have been included.
this report is generated by SSRS.
i am wondering if there is a way to HIDE column 13?
is there some kind of conditional formatting i can do?
to clarify here's my query:
select tat.*, tat.tat as tat2 from tat
it is organized in the report this way:
this data set [TAT] contains dummy data specifically for column 13
Specific columns in a column group can be hidden based on values with the following steps.
Right-click header of the column group you want to hide, Column Group -> Group Properties
Click on the Visibility pane and select Show or hide based on an expression radio button. Use an expression to determine when column is hidden.
True hides the column, False displays it. You will need to update the field name in my example to match your month field name.
Don't include column 13 in your select? If you are doing a select *, change it to Select col1, col2, ...., col12