Count district values based on another coulmn - sql

I have an SQL table of people with their event attendance status:
Person
EventStatus
Ethan Williams
NoShow
Ethan Williams
NoShow
Olivia Rodriguez
Arrived
Olivia Rodriguez
NoShow
Olivia Rodriguez
NoShow
Benjamin Chen
Arrived
Benjamin Chen
NoShow
Isabella Gomez
NoShow
I'm trying to filter and count only the people who never came to any event but can't get the right code to do this.
I was able to get this result using this code:
SELECT "Person" as "Person"
FROM TABLE
GROUP BY "Person"
HAVING (((COUNT(DISTINCT CASE
WHEN EventStatus = 'NoShow' THEN 1
ELSE NULL
END) - COUNT(DISTINCT CASE
WHEN EventStatus = 'Arrived' THEN 1
ELSE NULL
END)) > 0))
But using "GROUP BY" won't allow me to count the results.
The expected result I need is: 2
Which is the result these 2 people who are always "NoShow": Isabella Gomez, Ethan Williams.

People who never showed = all people - people who ever showed.
SELECT
COUNT(DISTINCT person)
-
COUNT(DISTINCT CASE WHEN EventStatus = 'Arrived' THEN person END)
FROM
yourTable

One approach uses aggregation along the lines of what you were trying:
WITH cte AS (
SELECT Person
FROM yourTable
GROUP BY Person
HAVING COUNT(CASE WHEN EventStatus = 'Arrived' THEN 1 END) = 0
)
SELECT COUNT(*) AS cnt
FROM cte;

Related

Substraction by the column just created in bigquery

My query is supposedly create new column based on the keyword in data using bigquery. For example if in data consists 'Mike' it will create Mike column, 'John' will create John column and the list goes on..
However, I want to create a 'other' column that is the substraction of overall name with the column I just created.
My code example (wrong at SUBSTRACT function):
SELECT
COUNT(Name) as n_name,
SUM(CASE WHEN Name LIKE '%MIKE%' THEN 1 ELSE 0 END) AS Mike,
SUM(CASE WHEN Name LIKE '%JOHN%' THEN 1 ELSE 0 END) AS John,
SUM(CASE WHEN Name LIKE '%MICHAEL%' THEN 1 ELSE 0 END) AS Michael,
.....
SUBSTRACT (n_name ,Mike and John) AS Others
FROM t
Is there any way to do some substraction by the column I just created ?
you can use below approach (BigQuery Standard SQL)
SELECT *,
n_name - Mike - John - Michael AS Other
FROM (
SELECT
COUNT(Name) AS n_name,
COUNTIF(Name LIKE '%MIKE%') AS Mike,
COUNTIF(Name LIKE '%JOHN%') AS John,
COUNTIF(Name LIKE '%MICHAEL%') AS Michael,
FROM t
)
SELECT
*
,n_name - Mike - John - Michael AS Other
FROM
(
SELECT
COUNT(Name) AS n_name
,COUNT(CASE WHEN Name like '%MIKE%' THEN 1 END) AS Mike
,COUNT(CASE WHEN Name LIKE '%JOHN%' THEN 1 END) AS John
,COUNT(CASE WHEN Name LIKE '%MICHAEL%' THEN 1 END) AS Michael
FROM
t
) aa

Fetching same rows that has multiple columns along with other rows

I have a view which results the following rows.
comp Sub-comp Lognum id Firname LAstname
AK AK-G 0 3897 ABC DEF
AK AK-G 0 5432 mark ray
MC MC-A 0 1234 john steve
MC MC-A 0 5678 dan pitcher
MC MC-A 0 9843 james robin
MC MC-A 84 1234 john steve
MC MC-A 84 5678 dan pitcher
MC MC-A 84 9843 james robin
I want to fetch the only the rows that has a lognum (if the same row has 0 also as lognum) along with the other rows that has just 0 as lognum.
The result table should be like this
comp Sub-comp Lognum id Firname LAstname
AK AK-G 0 3897 ABC DEF
AK AK-G 0 5432 mark ray
MC MC-A 84 1234 john steve
MC MC-A 84 5678 dan pitcher
MC MC-A 84 9843 james robin
And the outline of the query is as follows
create view view1 as
select
comp, Sub-comp, "00" as Lognum, id ,Firname ,LAstname
from
table A
inner joins---
UNION
select
select
comp, Sub-comp, Lognum, id ,Firname ,LAstname from
table B
inner joins----
;
Can anyone help?
Thanks!
Try this:
select * from(
select comp,
Sub-comp,
Lognum,
id,
Firname,
LAstname,
row_number() over(partition by id order by lognum desc) rn
from table_name)
where rn = 1;
This will show the line with the biggest lognum grouped by the ID.
This query should work, even in cases where, for a given id value, you have multiple "non-zero" lognum rows.
If you look at the where clause, rows with non-zero lognum values are always returned (t.Lognum != 0). But rows with zero lognum values will also return, but only if the t.rn = 1 condition is true, which will only happen if there aren't any other non-zero lognums for that same id (see the order by clause of the row_number() window function).
select t.comp,
t.Sub-comp,
t.Lognum,
t.id,
t.Firname,
t.LAstname
from (select t.*,
row_number() over (
partition by t.id
order by case when t.lognum = 0 then 1 else 0 end) as rn
from your_view t) t
where t.Lognum != 0 or t.rn = 1

Check for changes in all other columns based on similarities one column

FirstName LastName SSN Phone EncounterID
Justin Kelley 555-55-5555 517-555-1212 123456789
Justin Kelly 555-55-5555 517-555-1212 123456789
James Smith 444-44-4444 312-555-3434 99944444
James Smith 444-44-4444 312-555-3434 99944444
I have a table like the one above with millions of EncounterIDs. I need to know the number of times there is a difference (defect) in EACH column. My example output would be:
First Name - 2/2
Last Name - 1/2
SSN - 2/2
Phone - 2/2
Any help here?
The data that you basically want is the number of entities that have more than one value in a column.
This is most easily calculated on a column basis:
select sum(case when NumFirstNames <> 1 then 1 else 0 end) as DifferentFirstNames,
sum(case when NumLastNames <> 1 then 1 else 0 end) as DifferentLastNames,
sum(case when NumSSN <> 1 then 1 else 0 end) as DifferentSSN,
sum(case when NumPhone <> 1 then 1 else 0 end) as DifferentPhone
from (select EncounterId, count(*) as Num,
count(distinct FirstName) as NumFirstNames,
count(distinct LastName) as NumLastNames,
count(distinct SSN) as NumSSN,
count(distinct Phone) as NumPhone
from table t
group by EncounterId
) e;
You can format the results however you like.

Combine rows into one result and add results as different values in SQL

I have a table (people) that include the following information:
id cert_id type name
1 123 owner Paul
2 123 seller George
3 123 buyer steve
4 456 owner micheal
I also have a table (items) that includes the following:
id cert_id item_name
1 123 staples
2 123 cheese
3 123 iguanas
4 456 pie
Basically, what I want to do is have the results as the following:
cert_id owner_name seller_name buyer_name item_name
123 Paul George steve staples, cheese, iquanas
456 micheal pie
So far I have been able to use MAX(CASE WHEN people.type='owner' THEN people.name END) AS owner_name, but I cannot get the seller name to append to the other row ('im not sure if this is even possible via the SQL statement or if I should do some formatting with the results afterwards. Any advice on combining rows would be helpful, or a simple "not possible" would let me know what the limitations are.
Thanks in advance!
You should be able to use the following query to get the result:
select p.cert_id,
max(case when p.type = 'owner' then p.name end) owner_name,
max(case when p.type = 'seller' then p.name end) seller_name,
max(case when p.type = 'buyer' then p.name end) buyer_name,
array_agg(distinct i.item_name) Items
from people p
inner join items i
on p.cert_id = i.cert_id
group by p.cert_id;
See SQL Fiddle with Demo
This can be accomplished using INNER JOIN or LEFT-OUTER-JOIN...

SQL Group By Help Required

I have a table named People in the following format:
Date | Name.
When I count the people by Grouping By Name with
Select Date, Name, count(*)
From People
Group By Date, Name;
Will give the following
Date Name count(*)
10 Peter 25
10 John 30
10 Mark 25
11 Peter 15
11 John 10
11 Mark 5
But I would like the following result:
Date Peter John Mark
10 25 30 25
11 15 10 5
Is this possible? This is a simple example of a more complicated database. If someone helps me in solving this problem I will use the concept to implement it in my table
Thanks!
Select Date
, count(case when Name = 'Peter' then 1 else null end)
, count(case when Name = 'John' then 1 else null end)
, count(case when Name = 'Mark' then 1 else null end)
From People
Group By Date;
another option different from turbanoff's if, for some reason, you find yourself in a situation that you cant apply a group by:
Select distinct(P.Date),
(select count(*) from People where date=p.date and name='Peter') as Peter,
(select count(*) from People where date=p.date and name='John') as John,
(select count(*) from People where date=p.date and name='Mark') as Mark
From People P