Count Values from Table for each type - sql

I have the following table
UserId [nvarchar(128)], Rating [varchar(170)] :values will be mostly 1,2,3 but can have exceptions
Rating contains 3 values [1,2, or 3]
I want to get a result something like
UserId Count(1's),Count(2's) Count(3's)
1. 1001 10 8 2
2. 1002 5 10 3
Is it possible in a single query

Do a GROUP BY UserId to count for each user-id. Use CASE to count 1's, 2's and 3's separately:
select UserId,
count(case when Rating = 1 then 1 end) as [Count(1's)],
count(case when Rating = 2 then 1 end) as [Count(2's)],
count(case when Rating = 3 then 1 end) as [Count(3's)]
from tablename
group by UserId

Use a CASE statement in each COUNT and then GROUP BY UserId.
SELECT UserId, COUNT(CASE WHEN value = '1' THEN 1 END) AS [Count(1's)], COUNT(CASE WHEN value = '2' THEN 1 END) AS [Count(2's)], COUNT(CASE WHEN value = '3' THEN 1 END) AS [Count(3's)]
FROM yourtable
GROUP BY UserId

Use PIVOT:
SELECT
UserId,
COALESCE([1],0) [Count(1's)],
COALESCE([2],0) [Count(2's)],
COALESCE([3],0) [Count(3's)]
FROM
ýour_table
PIVOT
(COUNT([Rating])
FOR Rating
in([1],[2],[3])
)AS p
ORDER BY
UserId

Related

Sqlite group by distinct count

I have table of customers operations:
date, client_id, gender
1 1 M
1 1 M
1 2 M
1 2 M
1 3 F
2 1 M
2 1 M
2 1 M
2 2 M
2 2 M
2 3 F
2 3 F
2 4 F
2 5 M
2 5 M
etc
Desired output is:
date, amount of males, (also need amount of females)
1 2 1
2 3 2
I need to group it by date, so i did it, then my goal is to find amount of each gender in each grouped group.
so i tried to do this to count amount of males:
sum(case when gender = 'M' then 1 else NULL end) as 'M%'
but its counted clients id 1 and 2 two times each, but i need to count it distinct.
On example above i expect this to return 2 because 2 male. But it return 4 because distinct construction doesnt work.
I tried this but it doesnt work and count '1' in result:
sum(distinct case when gender = 'M' then 1 else NULL end) as 'M%'
It's easier to count from the distinct rows of the table.
Also, use SQLite's feature to treat boolean expressions as 1 for true and 0 for false so you can sum them instead of using CASE expressions:
SELECT date,
SUM(gender = 'M') [amount of males],
SUM(gender = 'F') [amount of females]
FROM (SELECT DISTINCT date, client_id, gender FROM tablename)
GROUP BY date
See the demo.
You seem to want conditional count(distinct):
select date,
count(distinct case when gender = 'M' then client_id end) as count_m,
count(distinct case when gender = 'F' then client_id end) as count_f
from t
group by date;

SQL: Multiple select that differ by only one condition

I've got a beginner question. My SQL table looks like:
| Date | Type | Manufacturer |
2016/04/01 A X
2016/04/01 B Y
2016/04/02 B X
2016/05/07 A Z
... ... ...
My aim is to count the quantity of "Types" by manufacturers between two dates. I would like to get a result like following:
| Manufacturer | Quantity_TypeA | Quantity_TypeB |
X 1 1
Y 0 1
Z 1 0
My query looks like:
select Manufacturer as Manufacturer,
COUNT(*) as Quantity_TypeA
From MyTable
Where [Type] = 'A' and
Date between '20150101' and '20160930',
COUNT(*) as Quantity_TypeB
From MyTable
Where [Type] = 'B' and
Date between '20150101' and '20160930'
group by Manufacturer Order by Quantity_TypeA DESC
I have also tried to use functions like CASE on the Type and it didn't work. I am missing something but what?
Try this
select Manufacturer as Manufacturer,
SUM(case when [Type] = 'A' then 1 else 0 end) as Quantity_TypeA,
SUM(case when [Type] = 'B' then 1 else 0 end) as Quantity_TypeB
From MyTable
Where
Date between '20150101' and '20160930'
group by Manufacturer
Use case expressions to do conditional counting:
select Manufacturer as Manufacturer,
COUNT(case when [Type] = 'A' then 1 end) as Quantity_TypeA,
COUNT(case when [Type] = 'B' then 1 end) as Quantity_TypeB
from MyTable
where Date between '20150101' and '20160930',
group by Manufacturer
order by Quantity_TypeA DESC
count() does only count non-null values. The case expressions either return 1 or null, i.e. only A's or B's are counted.

SQL count of values from different columns

I've got a Dog table. Each dog has Breed and can have 0 to 2 photos. I need to recieve count of photos of all dogs for each breed: table with BreedId and matching PhotosCount. So result table should be:
BreedID|PhotosCount
-------------------
1 |3
-------------------
2 |1
-------------------
This should do the trick:
SELECT BreedID AS B, COUNT(Photo1) + COUNT(Photo2) AS C
FROM Dog
GROUP BY BreedID
COUNT aggregate function simply doesn't take into consideration NULL values. If, for a specific BreedID, all values of either Photo1 or Photo2 are NULL, then COUNT returns 0.
This should work in single scan:
SELECT
BreedID,
SUM(CASE WHEN Photo1 IS NOT NULL THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Photo2 IS NOT NULL THEN 1 ELSE 0 END) [Count]
FROM Table
GROUP BY BreedID
Use Group By and SUM Of Photo1 and Photo2:
Note: If you wants the output for each dog you have to include DogId in group clause.
;WITH T AS
(
SELECT
BreedId,
SUM (CASE ISNULL(Photo1,0) WHEN 1 THEN 1 ELSE 0 END) AS Photo1,
SUM (CASE ISNULL(Photo2,0) WHEN 1 THEN 1 ELSE 0 END) AS Photo2
FROM TableName
Group By BreedId
)
SELECT
BreedId,
SUM(Photo1+Photo2) AS TotalPhoto
FROM T
Or Simply
SELECT
BreedId,
SUM (CASE ISNULL(Photo1,0) WHEN 1 THEN 1 ELSE 0 END + CASE ISNULL(Photo2,0) WHEN 1 THEN 1 ELSE 0 END) AS TotalPhoto
FROM TableName
Group By BreedId
SELECT BreedID AS Breed, COUNT(Photo1) + COUNT(Photo2) AS #ofPhotos
FROM Dog
GROUP BY BreedID;

How to find correlated values in Oracle?

Say you have a table such as:
id foreign_key status
------------------------
1 1 new
2 1 incative
3 1 approved
4 2 new
5 2 new
6 2 approved
7 3 new
8 3 approved
9 4 approved
How to find records where the for a given foreign_key there is only one record in status new and the other are approved, like in case of foreign_key 3?
select foreign_key from table
group by foreign_key
having
abs(1 - count(case status when 'new' then 1 end)) +
abs(count(1) - 1 - count(case status when 'approved' then 1 end)) = 0
Something like this
Select *
from
(
Select foreign_key
from table
where status = 'new'
group by foreign_key
having count(1) = 1
) new_st
inner join
(
Select foreign_key
from table
where status = 'approved'
group by foreign_key
having count(1) = (select count(1)-1 from table t1 where t1.foreign_key =foreign_key)
) app_st
on new_st.foreign_key = app_st.foreign_key
SELECT *
FROM (SELECT id, foreign_key, status,
COUNT (DECODE (status, 'new', 1))
OVER (PARTITION BY foreign_key)
new_count,
COUNT (DECODE (status, 'approved', 1))
OVER (PARTITION BY foreign_key)
approved_count,
COUNT (status) OVER (PARTITION BY foreign_key) total_count
FROM mytable)
WHERE new_count = 1 AND new_count + approved_count = total_count;
I have used 3 different counts. One to count new, one to count approved and one to count all status. Finally select only those records where new_count = 1 and new_count + approved_count is equal to total_count.
Demo here.
EDIT: Can add approved_count > 0 condition to make sure that there is atleast one approved status.

How do I return count and not count in a SQL query?

If I have a table
AgentID | IsNew | TeamID
1 N 1
2 Y 2
3 Y 2
4 N 2
5 Y 1
I want to return the following from a query:
Team | CountIsNew = N | CountIsNew = Y
1 1 1
2 1 2
Is there a way I can do this?
Using Oracle 10
SELECT team, SUM(DECODE(IsNew, 'N', 1, 0)), SUM(DECODE(IsNew, 'Y', 1, 0))
FROM mytable
GROUP BY
team
SELECT TeamId
, SUM(CASE WHEN IsNew = 'N' THEN 1 ELSE 0 END) AS CountIsNotNew
, SUM(CASE WHEN IsNew = 'Y' THEN 1 ELSE 0 END) AS CountIsNew
FROM Agent
GROUP BY TeamId
Yet another way - COUNT doesn't count NULLs (except for COUNT(*)):
SELECT TeamId,
COUNT(DECODE(IsNew,'N',1)) CountIsNotNew,
COUNT(DECODE(IsNew,'Y',1)) CountIsNew
FROM Agent
GROUP BY TeamId;
Or, if you prefer CASE:
SELECT TeamId,
COUNT(CASE IsNew WHEN 'N' THEN 1 END) CountIsNotNew,
COUNT(CASE IsNew WHEN 'Y' THEN 1 END) CountIsNew
FROM Agent
GROUP BY TeamId;
(note: the "1"s could be any literal value)