SQL Pivot using count - sql

I have a table which has the following entries
ID | column | value
------------------------
1 | status | DONE
2 | status | FAILED
1 | progress | Green
2 | progress | Red
i want the output as
ID | DONE | FAILED | GREEN | RED
1 | 1 | 0 | 1 | 0
2 | 0 | 1 | 0 | 1
Please let me know the query. I have tried pivot but not getting the results.

Here is a standard pivot query solution which does not use SQL Server's built in PIVOT capability:
SELECT ID,
SUM(CASE WHEN value = 'DONE' THEN 1 ELSE 0 END) AS DONE,
SUM(CASE WHEN value = 'FAILED' THEN 1 ELSE 0 END) AS FAILED,
SUM(CASE WHEN value = 'Green' THEN 1 ELSE 0 END) AS GREEN,
SUM(CASE WHEN value = 'Red' THEN 1 ELSE 0 END) AS RED
FROM yourTable
GROUP BY ID

SELECT *
FROM atable
PIVOT (
COUNT(column)
FOR value in ([DONE], [FAILED], [GREEN], [RED])
) p

Related

SQL- count the non NULL values and count the rows that has string "1"

I'm trying to count non null row in a column but it's counting all the rows and and count the rows in a column that has string "1".
I was able to count the rows in a column that has string "1" for the 1st column but on the 2nd one, it's count the "0" too.
I've seen some articles here but it didn't resolved the issue.
SELECT NAME as Agent_Name, COUNT(case when Thumbs_Up= 1 then 1 else null end) as Thumbs_Up,
COUNT(case when No_Solution_Found =1 then 1 else null end) as No_Solution,
COUNT(case when Save is null then 0 else 1 end) as Total_Saves,
FROM table
GROUP BY NAME
Table:
Name | Thumbs_up | No_Solution_Found | Save
Jonathan | 1 | 0 | Saved
Mike | 0 | 1 | Null
Peter | 1 | 0 | Null
Mike | 1 | 0 | Saved
Peter | 0 | 1 | Saved
Mike | 1 | 0 | Saved
Peter | 0 | 1 | Saved
Expected results:
Name | Thumbs_up | No_Solution | Total_Save
Jonathan | 1 | 0 | 1
Mike | 2 | 1 | 2
Peter | 1 | 2 | 2
Try with SUM instead of COUNT
SELECT NAME as Agent_Name,
SUM(case when Thumbs_Up = 1 then 1 else 0 end) as Thumbs_Up,
SUM(case when No_Solution_Found =1 then 1 else 0 end) as No_Solution,
SUM(case when Save is null then 0 else 1 end) as Total_Saves,
FROM table
GROUP BY NAME
Since only the Save column has NULLs, I assume that's the column you have the problem with.
In your query you wrote:
COUNT(case when Save is null then 0 else 1 end) as Total_Saves,
That is, you're replacing NULL by 0, which is a non null value and therefore is counted.
You presumable wanted to just write:
COUNT(Save) as Total_Saves
(And BTW, there is a comma after as Total_Saves in your query, that doesn't belong there, as no other column expression follows.)
Try the following query-:
Select
Name,
sum(Thumbs_up),
sum(No_Solution_Found),
count(case when [Save] is not null then 1 else null end) as Total_save
from TABLE
group by Name
SQL Server 2014

SQL Grouping entries with a different value

Let's assume I have a report that displays an ID and VALUE from different tables
| ID | VALUE |
|----|-------|
1 | 1 | 1 |
2 | 1 | 0 |
3 | 1 | 1 |
4 | 2 | 0 |
5 | 2 | 0 |
My goal is to display this table with grouped IDs and VALUEs. My rule to grouping VALUEs would be "If VALUE contains atleast one '1' then display '1' otherwise display '0'".
My current SQL is (simplified)
SELECT
TABLE_A.ID,
CASE
WHEN TABLE_B.VALUE = 1 OR TABLE_C.VALUE NOT IN (0,1,2,3)
THEN 1
ELSE 0
END AS VALUE
FROM TABLE_A, TABLE_B, TABLE_C
GROUP BY
TABLE_A.ID
(CASE
WHEN TABLE_B.VALUE = 1 OR TABLE_C.VALUE NOT IN (0,1,2,3)
THEN 1
ELSE 0
END)
The output is following
| ID | VALUE |
|----|-------|
1 | 1 | 1 |
2 | 1 | 0 |
3 | 2 | 0 |
Which is half way to the output I want
| ID | VALUE |
|----|-------|
1 | 1 | 1 |
2 | 2 | 0 |
So my Question is: How do I extend my current SQL (or change it completely) to get my desired output?
If you are having only 0 and 1 as distinct values in FOREIGN_VALUE column then using max() function as mentioned by HoneyBadger in the comment will fulfill your requirement.
SELECT
ID,
MAX(FOREIGN_VALUE) AS VALUE
FROM (SELECT
ID,
CASE WHEN FOREIGN_VALUE = 1
THEN 1
ELSE 0
END AS FOREIGN_VALUE
FROM TABLE,
FOREIGN_TABLE)
GROUP BY
ID;
Assuming value is always 0 or 1, you can do:
select id, max(value) as value
from t
group by id;
If value can take on other values:
select id,
max(case when value = 1 then 1 else 0 end) as value
from t
group by id;

Count how many columns are bigger than 0

I have a table that has some numeric columns. I need to count how many have values that are greater than 0, and to add it as a new column.
For example:
The current table is:
A | B | C | D | E |
2 | 4 | 0 | 8 | 0 |
0 | 0 | 0 | 0 | 1 |
The output would be:
A | B | C | D | E | "New column"
2 | 4 | 0 | 8 | 0 | 3
0 | 0 | 0 | 0 | 1 | 1
You can do this with the brute force method:
select t.*,
((case when a > 0 then 1 else 0 end) +
(case when b > 0 then 1 else 0 end) +
(case when c > 0 then 1 else 0 end) +
(case when d > 0 then 1 else 0 end) +
(case when e > 0 then 1 else 0 end)
) as NewColumn
from currenttable t;
If you actually want a new column in the table, then you should do:
alter the table to add the new column
run an update statement similar to the above select
consider a trigger to keep the value up-to-date
EDIT:
Alex's comment is worth mentioning. In the more recent versions of Oracle, you can add a virtual column which would do this calculation as part of the table definition itself. Virtual columns are definitely a better way to solve this problem than adding a new non-virtual column to the table.

Postgres simple 'pivot' table

If I have a table of data as such
name | type | count
test | blue | 6
test2 | red | 3
test | red | 4
How can I query it such that I get a table:
name | num_red | num_blue
test | 4 | 6
test2 | 3 | 0
I can of course select count(*) where type=blue etc but I can't think of how to count multiple types within one query like this.
Thanks!
You can use CASE in you select clause.
SELECT name,
SUM(CASE WHEN type = 'red' THEN "count" ELSE 0 END) numred,
SUM(CASE WHEN type = 'blue' THEN "count" ELSE 0 END) numblue
FROM tableName
GROUP BY name
SQLFiddle Demo

sql group by where statement

lets say i have this table
user|group|acceptance
1 | a | -1
2 | a | 2
3 | b | 1
4 | b | 2
5 | b | 2
6 | c | -1
how do i get count how many users in each group have acceptance not -1 but still list the group having 0 count
so result would be like
group | count
a | 1
b | 3
c | 0
thanks for the help
SELECT [group], SUM(CASE acceptance WHEN -1 THEN 0 ELSE 1 END) AS [count]
FROM MyTable
GROUP BY [group]
Count(Col) doesn't count NULL values. So pass a non null value where acceptance <> -1 (and it will default to passing null for the case not handled)
SELECT [group],
COUNT(CASE WHEN acceptance <> -1 THEN 1 END) AS [count]
FROM tbl
GROUP BY [group]