Logic / query required for scenario and pivot is not helping me - sql

I have following table structure
ID Status1 status 2 status 3
A1 1 0 1
A1 1 1 0
A2 1 0 0
A3 0 1 1
I want to collect it as one record like this (only 1's count for each column)
A1 2 1 1
A2 1 1 0
A3 0 1 1
I have tried using pivot but actually not the one am getting it correctly.
Please give some thought.

Hope you looking for this
Select ID, SUM(Status1) As Status1, SUM(Status2) As Status2, SUM(Status3) As Status3
from MyTable
Group By ID

Related

SQL Query to get multiple resultant on single column

I have a table that looks something like this:
id name status
2 a 1
2 a 2
2 a 3
2 a 2
2 a 1
3 b 2
3 b 1
3 b 2
3 b 1
and the resultant i want is:
id name total count count(status3) count(status2) count(status1)
2 a 5 1 2 2
3 b 4 0 2 2
please help me get this result somehow, i can just get id, name or one of them at a time, don't know how to put a clause to get this table at once.
Here's a simple solution using group by and case when.
select id
,count(*) as 'total count'
,count(case status when 3 then 1 end) as 'count(status1)'
,count(case status when 2 then 1 end) as 'count(status3)'
,count(case status when 1 then 1 end) as 'count(status2)'
from t
group by id
id
total count
count(status3)
count(status2)
count(status1)
2
5
1
2
2
3
4
0
2
2
Fiddle
Here's a way to solve it using pivot.
select *
from (select status,id, count(*) over (partition by id) as "total count" from t) tmp
pivot (count(status) for status in ([1],[2],[3])) pvt
d
total count
1
2
3
3
4
2
2
0
2
5
2
2
1
Fiddle

SQL Server : how can I get difference between counts of total rows and those with only data

I have a table with data as shown below (the table is built every day with current date, but I left off that field for ease of reading).
This table keeps track of people and the doors they enter on a daily basis.
Table entrance_t:
id entrance entered
------------------------
1 a 0
1 b 0
1 c 0
1 d 0
2 a 1
2 b 0
2 c 0
2 d 0
3 a 0
3 b 1
3 c 1
3 d 1
My goal is to report on people and count entrances not used(grouping on people), but ONLY if they entered(entered=1).
So using the above table, I would like the results of query to be...
id count
----------
2 3
3 1
(id=2 did not use 3 of the entrances and id=3 did not use 1)
I tried queries(some with inner joins on two instances of same table) and I can get the entrances not used, but it's always for everybody. Like this...
id count
----------
1 4
2 3
3 1
How do I not display results id=1 since they did not enter at all?
Thank you,
You could use conditional aggregation:
SELECT id, count(CASE WHEN entered = 0 THEN 1 END) AS cnt
FROM entrance_t
GROUP BY id
HAVING count(CASE WHEN entered = 1 THEN 1 END) > 0;
DBFiddle Demo

Column Integration per registry

I'm trying to get the results of a table ordered by different values in a column, but I want to show them in the same row... For example, my table looks like this.
PR_ID SOLUTION DESCRIPTION
------------------------- ---------- --------------------------------------------------
A1 1 Description 1
A2 2 Description 2
A3 3 Description 1
A4 1 Description 3
B1 1 Description 1
B2 2 Description 2
C1 3 Description 1
C2 2 Description 2
8 rows selected
And I want the results to show something like this:
DESCRIPTION SOL_Up SOL_Down SOL_No_Valid
------------------------------ -------- ---------- -------------
Description 1 2 0 3
Description 2 0 3 0
Description 3 1 0 0
I have the cases working, but when i tried to put them in the same row it sends me nulls, which I dont mind the nulls for 0's but I need them on the same row.
select
description, Sol_Up, Sol_Down, Sol_No_Valid, count(1)
from
(
select description,
case when Solution = 1 then 'Up' end Sol_Up,
case when Solution = 2 then 'Down' end Sol_Down,
case when Solution <= 0 or Solution >= 3 then 'No_Valid' end Sol_No_Valid
from PRUEBAS_SOL
)
group by
description, Sol_Up, Sol_Down, Sol_No_Valid
order by Description;
But the results are nowhere near what I need...
DESCRIPTION SO SOL_ SOL_NO_V COUNT(1)
-------------------------------------------------- -- ---- -------- ----------
Description 1 Up 2
Description 1 No_Valid 2
Description 2 Down 3
Description 3 Up 1
select description
,count (case when Solution = 1 then 1 end) Sol_Up
,count (case when Solution = 2 then 1 end) Sol_Down
,count (case when Solution not in (1,2) then 1 end) Sol_No_Valid
from PRUEBAS_SOL
group by description
order by Description
;

SQL Query. limit an update per rows if condition is X and Y for the same ID number

Have the following table tblTrans where
Trans_ID Trans Sequence Trans_PointsEarned Trans_PointsApplied
4452 1 1 1
4452 2 1 1
4452 3 0 1
4462 1 1 1
4462 2 1 1
4462 3 1 1
4462 4 1 1
4462 5 1 1
9101 1 0 1
9101 2 0 1
9101 3 0 1
9101 4 0 1
(useless table doesnt work)
I need to set the following on another field per every customer ID.
So Customer_OverallPoints
4452 = 2 (doesn't count 0's)
4462 = 4 (I want to cap the points to 4 based on the sequence and transID and customerID)
9101 = 0 (dont count 0's).
This needs to be applied to thousands of records based on customerID and TransID where Trans_Sequence is within the same Trans_ID and it only counts the first 4 rows that have the Trans_pointsEarned = 1.
I tried putting a psuedocode together but it just looked ridicilous and I can't even come up with the logic for this.
Thanks
Assuming that TransId is really the customer id, I think the basic logic is just an aggregation:
select t.TransId,
(case when sum(t.Trans_PointsEarned) > 4 then 4
else sum(t.Trans_PointsEarned)
end) as Customer_OverallPoints
from tblTrans t
group by t.TransId;
You can put this into an update statement as:
update customers c
set Customer_OverallPoints = (select (case when sum(t.Trans_PointsEarned) > 4 then 4
else sum(t.Trans_PointsEarned)
end)
from tblTrans t
where t.TransId = c.CustomerId
);

Formatting the results of a query

Let's say I have the following table:
first second
A 1
A 1
A 2
B 1
B 2
C 1
C 1
If I run the following query:
select first, second, count(second) from tbl group by first, second
It will produce a table with the following information:
first second count(second)
A 1 2
A 2 1
B 1 1
B 2 1
C 1 2
How can I write the query so that I am given the information with the options from the second column as columns and the values for those columns being the count like this:
first 1 2
A 2 1
B 1 1
C 2 0
You can use CASE:
SELECT "first",
SUM(CASE WHEN "second" = 1 THEN 1 ELSE 0 END) AS "1",
SUM(CASE WHEN "second" = 2 THEN 1 ELSE 0 END) AS "2"
FROM tbl
GROUP BY "first"