get the closest - sql

How do I get output in the below format using sql?
I am able to do it with case sum, but I am not able to get unique user count in the same line.
id unique_users male_count female_count
101 3 1 2
201 1 0 1
.
.

select id,
count(distinct user) as unique_users,
sum(case when gender = 'M' then 1 else 0 end) as male_count,
sum(case when gender = 'F' then 1 else 0 end) as female_count
from your_table
group by id

Alternative counts distinct males and females.
SELECT
ID,
COUNT(DISTINCT "USER") AS unique_users,
COUNT(DISTINCT DECODE(gender,'M',"USER")) AS male_count,
COUNT(DISTINCT DECODE(gender,'F',"USER")) AS female_count
FROM your_table
GROUP BY ID
ORDER BY ID;
And the same but without the Oracle specific DECODE function.
SELECT
ID,
COUNT(DISTINCT "USER") AS unique_users,
COUNT(DISTINCT CASE gender WHEN 'M' THEN "USER" ELSE NULL END) AS male_count,
COUNT(DISTINCT CASE gender WHEN 'F' THEN "USER" ELSE NULL END) AS female_count
FROM your_table
WHERE ID = 101
GROUP BY ID
ORDER BY ID;
I've quoted "USER" as it has a specific meaning in Oracle.

Related

How to find number of nulls in a table SQL

Let's say that I have an employee table. And it has columns like name, salary, and age. If I want to check if there any nulls in the name. I gotta write
SELECT name FROM EMPLOYEE
WHERE name IS NULL;
But what should I do to see the number of nulls each column has?
Probably the simplest method is:
select count(*) - count(name) as num_name_nulls,
count(*) - count(col1) as num_col1_nulls,
. . .
from employee;
However, what I do in this situation is just select the counts:
select count(*), count(name), count(col1), . . .
from employee;
Then I eyeball the result to see if the counts are not equal.
I assume you want to see nulls for a column, you can apply conditional aggregation.
SELECT COUNT(CASE WHEN name is null then 1 end) AS Name_NullCount,
COUNT(CASE WHEN salary is null then 1 end) as salary_nullCount,
COUNT(CASE WHEN age is null then 1 end) as age_nullcount
FROM EMPLOYEE;
You can use below query but it depends on number of columns. It will give number of nulls each row has.
select
((case when column1 is null then 1 else 0 end)
+ (case when column2 is null then 1 else 0 end)
----------------------------------------
----------------------------------------
+(case when columnN is null then 1 else 0 end))
from TableName
For your case
select
((case when name is null then 1 else 0 end)
+(case when salary is null then 1 else 0 end)
+(case when age is null then 1 else 0 end))
from employee
you can find Null values per row from following query
SELECT
(
(CASE WHEN name IS NULL THEN 1 ELSE 0 END)+
...
...
+(CASE WHEN colName IS NULL THEN 1 ELSE 0 END)
) AS sum_of_nulls
FROM EMPLOYEE
WHERE EmpId = 49
where colName is your Db Column Name
select
sum(case
when name is null then 1
when name is not null tehn 0
end) cname,
sum(case
when salary is null then 1
when salary is not null then 0
end) csalary,
...
from employee
limit 1;

Combine results into one line

How do I make these results appear on one line, in SQL?
You can use a GROUP BY to do this:
SELECT school_id, school_name, grade, SUM(CASE WHEN Gender='F' THEN 1 ELSE 0 END) as female, SUM(CASE WHEN Gender='M' THEN 1 ELSE 0 END) as male
FROM yourtable
GROUP BY school_id, school_name, grade;

Comparing values in two columns and returning values on conditional bases using sql hive

I have two columns, I want to get an output based on a comparative basis of both. My data is somewhat like:
Customer Id status
100 A
100 B
101 B
102 A
103 A
103 B
So a customer can have a status A or B or both, I have to segrerate them on customer id basis for a status. If status A and B then return happy, if only A, return Avg and if only B return Sad.
try the below query,
SELECT DISTINCT Customer_Id,
(CASE WHEN COUNT(*) OVER(PARTITION BY Customer_Id) > 1 THEN 'happy'
WHEN Tstatus = 'A' THEN 'Avg'
ELSE 'Sad'END) AS New_Status
FROM #table1
GROUP BY Customer_Id,Tstatus
if Customer Id and status is a unique combination then
STEP 1: use case to determine a or b
SELECT customer id
,CASE WHEN avg(case when [status] ='A' then 0 else 2 end)
FROM [Your Table]
group by[customer id]
and step 2 will be casing avg into result: like this
SELECT customer id
,CASE WHEN (avg(case when [status] ='A' then 0 else 2 end)) = 1 THEN 'happy' ELSE WHEN (avg(case when [status] ='A' then 0 else 2 end)) = 0 THEN 'Avg' ELSE 'Sad' END
FROM [Your Table]
group by[customer id]
I would do this simply as:
select customer_id,
(case when min(status) <> max(status) then 'happy'
when min(status) = 'A' then 'avg'
else 'sad'
end)
from t
where status in ('A', 'B')
group by customer_id

How to have condition inside count SQL?

I already tried this code:
SELECT Count(Gender) As MaleCount, Count(Gender) As FemaleCount
FROM [Session4].[dbo].[Survey]
Where Gender = 'M' or Gender = 'F'
I can't get the accurate data when counting with two different conditions in one query.
Pictures below:
This is the result.
This is the original data
SELECT TOP (1000) [Departure]
,[Arrival]
,[Age]
,[Gender]
,[CabinType]
,[Q1]
,[Q2]
,[Q3]
,[Q4]
FROM [Session4].[DBO].[Survey]
count explain :
COUNT(*) counts all rows
COUNT(column) counts non-null value
COUNT(distinct column) counts distinct non-null value
COUNT(1) is the same as COUNT(*)
Use case/when + sum :
SELECT
sum(case when Gender = 'M' then 1 else 0 end ) As MaleCount,
sum(case when Gender = 'F' then 1 else 0 end ) As FemaleCount
FROM [Session4].[dbo].[Survey]
will produce somethings like this :
MaleCount | FemaleCount
1000 | 1255
Another way is using simple goup by
SELECT
Gender,
Count(*)
FROM [Session4].[dbo].[Survey]
GROUP BY
Gender
will produce :
Gender | Count
M | 1000
F | 1255
Try this out:
SELECT sum(case when Gender = 'M' then 1 else 0 end) As MaleCount,
sum(case when Gender = 'F' then 1 else 0 end) As FemaleCount
FROM [Session4].[dbo].[Survey]
Let me know in case of any doubts.

Count Values from Table for each type

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