I'm trying to display 3 columns in a table.
Something like:
ZIPCODE
SUBSCRIBERS
MEMBERS
12345
5
10
12346
3
8
In which each zipcode is a distinct zipcode that has a number of "subscribers" within it. The subscribers would be the original employee, that can just be defined as DEPNO=0 (they are the original employee and not a dependent), the members would just be everyone in the zipcode which I am able to get with a statement that looks like the SQL below. I am pulling from a table called EMPDEP
SELECT DISTINCT ZIPCODE, COUNT(*) OVER (PARTITION BY ZIPCODE) as Subscribers FROM EMPDEP where depno=0
This statement will get me a Subscriber count but I want the total member count in there as well which would just be
SELECT DISTINCT ZIPCODE, COUNT(*) OVER (PARTITION BY ZIPCODE) as Members FROM EMPDEP
but getting all 3 of these in 1 query is killing me as I can't get the nesting down correctly, at least I'm assuming I will need that?
Any tips on how to do this?
Huh? Why are you using window functions? Just use aggregation:
SELECT ZIPCODE, COUNT(*) as Members,
SUM(CASE WHEN depno = 0 THEN 1 ELSE 0 END) as Subscribers
FROM EMPDEP
GROUP BY ZIPCODE;
Related
I have an example data as below.
I want to calculate user count per city and user count per country.
Here's what I want:
How can I implement it in BigQuery as simple as possible?
Thanks a million!
You can use analytical function as follows:
select distinct country, city,
count(distinct username) over (partition by country, city) as distinct_users_per_city,
count(distinct username) over (partition by country) as distinct_users_per_country
from your_Table t
I want to calculate user count per city and user count per country
I feel like Jessie from Tokyo and Jessie from Okinawa are two different users and needs to be counted as such for country count! Same goes for Jack from Chicago and Jack from New York!
Below code does this
select distinct country, city,
count(distinct username) over (partition by country, city) as user_count_per_city,
count(distinct username || '|' || city) over(partition by country) as user_count_per_country
from `project.dataset.table`
if applied to sample data in your question - output is
which is different from yours (expected/presented in the question) for above described reason
I have the following table.
Fights (fight_year, fight_round, winner, fid, city, league)
I am trying to query the following:
For each year that appears in the Fights table, find the city that held the most fights. For example, if in year 1992, Jersey held more fights than any other city did, you should print out (1992, Jersey)
Here's what I have so far but I keep getting the following error. I am not sure how I should construct my group by functions.
ERROR: column, 'ans.fight_round' must appear in the GROUP BY clause or be used in an aggregate function. Line 3 from (select *
select fight_year, city, max(*)
from (select *
from (select *
from fights as ans
group by (fight_year)) as l2
group by (ans.city)) as l1;
In Postgres, I would recommend aggregation and distinct on:
select distinct on (flight_year) flight_year, city, count(*) cnt
from flights
group by flight_year, city
order by flight_year, count(*) desc
This counts how many fights each city had each year, and retains the city with most fight per year.
If you want to allow ties, then use window functions:
select flight_year, city, cnt
from (
select flight_year, city, count(*) cnt,
rank() over(partition by flight_year order by count(*) desc) rn
from flights
group by flight_year, city
) f
where rn = 1
Although row_number is the easiest way as done by #GMB. Can try this alternative as well
select city, fight_year
from fights
group by city, fightyear
having count(*) = sum(case when fid is not null then 1 end)
I have a table with names of countries. The country names are duplicated in the table. Eg say there are 8 rows in the table, 5 rows with country Germany and 3 with country UK. I want to get count the countries in the table (eg. I should get the number 2). But I am unable to come up with the query
I tried SELECT Country FROM Customers; but that will give me 8 rows. I tried SELECT DISTINCT Country FROM Customers; but that gives me 2 rows. I tried using count as SELECT DISTINCT Count(Country) FROM Customers; but I get 8 (probably because DISTINCT is applied on result set of SELECT Count(Country) FROM Customers; How could I get 2?
You can use distinct inside count:
select count(distinct country)
from customers;
Which is equivalent to:
select count(*)
from (
select distinct country
from customers
where country is not null
) t;
use inside distinct
SELECT count( distinct Country) FROM Customers
You can use distinct country within count as below:
SELECT count(DISTINCT country)
FROM customers;
You can use distinct country within count and group by country for getting country name as well:
SELECT count(1), country
FROM customers
GROUP BY country;
Here is one way to do this using analytic functions:
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(*)) cnt
FROM customers
GROUP BY country
ORDER BY cnt DESC
LIMIT 1;
I have read answers to similar questions but I cannot find a solution to my particular problem.
I will use a simple example to demonstrate my question.
I have a table called 'Prizes' with two columns: Employees and Awards
The employee column lists the employee's ID and award shows a single award won by the employee. If an employee has won multiple awards their ID will be listed in multiple rows of the table along with each unique award.
The table would look as follows:
Employee AWARD
1 Best dressed
1 Most attractive
2 Biggest time waster
1 Most talkative
3 Hardest worker
4 Most shady
3 Most positive
3 Heaviest drinker
2 Most facebook friends
Using this table, how would I select the ID's of the employees who won the most awards?
The output should be:
Employee
1
3
For the example as both these employees won 3 awards
Currently, the query below outputs the employee ID along with the number of awards they have won in descending order:
SELECT employee,COUNT(*) AS num_awards
FROM prizes
GROUP BY employee
ORDER BY num_awards DESC;
Would output:
employee num_awards
1 3
3 3
2 2
4 1
How could I change my query to select the employee(s) with the most awards?
A simple way to express this is using rank() or dense_rank():
SELECT p.*
FROM (SELECT employee, COUNT(*) AS num_awards,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM prizes
GROUP BY employee
) p
WHERE seqnum = 1;
Being able to combine aggregation functions and analytic functions can make these queries much more concise.
You can use dense_rank to get all the rows with highest counts.
with cnts as (
SELECT employee, count(*) cnt
FROM prizes
GROUP BY employee)
, ranks as (select employee, cnt, dense_rank() over(order by cnt desc) rnk
from cnts)
select employee, cnt
from ranks where rnk = 1
I have a table with all U.S. zip codes. each row contains the city and state name for the zip code. I'm trying to get a list of cities that show up in multiple states. This wouldn't be a problem if there weren't X amount of zip codes in the same city...
So basically, I just want to the city in a state to count as 1 instead of it counting the city/state 7 times because there are 2+ zip codes in that city/state...
I'm not really sure how to do this. I know I need to use count but how do I tell the mysql to only count a given city/state combo as 1?
SELECT City, Count(City) As theCount
FROM (Select City, State From tblCityStateZips Group By City, State) As C
GROUP By City
HAVING COUNT Count(City) > 1
This would return all cities, with count, that were contained in more than one state.
Greenville 39
Greenwood 2
GreenBriar 3
etc.
First group on state and city, then group the result on city:
select City
from (
select State, City
from ZipCode
group by State, City
) x
group by City
having count(*) > 1
Will this do the trick
Select CityName, Count (Distinct State) as StateCount
From CityStateTable
Group by CityName
HAVING Count (Distinct State) > 1
Try using a select distinct
SELECT DISTINCT city, state FROM table GROUP BY city
You probably should have created a separate table for zip codes then to avoid the duplication.
You want to look into the GROUP BY Aggregate.