Get mixed in sql query - sql

I've got a table in postgresql include in countries and bird species column. I want to get what country has the most number of bird species.How can I do that? any suggestion?

You can use dense_rank to get all the countries with the highest number of species.
select country from
(
select country, dense_rank() over(order by count(*) desc) as rnk
from yourtable
) t
where rnk = 1

A typical way to solve this is using group by and limit/fetch first 1 row only:
select country, count(*) as cnt
from t
group by country
order by count(*) desc
limit 1;
Note: in case multiple countries are tied, then this will only return one of them.

Related

Multiple maximum values

So I am on SQLite and have the following table and need to print the two names to which correspond the highest number of wins(25). By using the MAX() function, I only get the first of the two rows. How is it possible to print both rows that have the maximum value for wins?
If you query this way, it will return the highest two rows.
SELECT
name,
Wins
FROM
table_name
ORDER BY Wins DESC
LIMIT 2;
Use RANK() window function:
SELECT name, Wins
FROM (
SELECT *, RANK() OVER(ORDER BY Wins DESC) rnk
FROM tablename
)
WHERE rnk = 1
This will return all the rows which will have the max number of Wins because all of them will be ranked as 1.
if you dont mind nested selects I think this should be getting all records have max wins
select name, wins from table where wins=(select max(wins) from table )
All names with top 2 score
WITH maxw (wins) AS(
SELECT DISTINCT wins
FROM tbl
ORDER BY wins DESC
LIMIT 2
)
SELECT tbl.*
FROM tbl
JOIN maxw ON tbl.wins = maxw.wins;

How do I create a new SQL table with custom column names and populate these columns

So I currently have an SQL statement that generates a table with the most frequent occurring value as well as the least frequent occurring value in a table. However this table has 2 rows with the row values as well as the fields. I need to create a custom table with 2 columns with min and max. Then have one row with one value for each. The value for these columns needs to be from the same row.
(SELECT name, COUNT(name) AS frequency
FROM firefighter_certifications
GROUP BY name
ORDER BY frequency DESC limit 1)
UNION
(SELECT name, COUNT(name) AS frequency
FROM firefighter_certifications
GROUP BY name
ORDER BY frequency ASC limit 1);
So for the above query I would need the names of the min and max values in one row. I need to be able to define the name of new columns for the generated SQL query as well.
Min_Name | Max_Name
Certif_1 | Certif_2
I think this query should give you the results you want. It ranks each name according to the number of times it appears in the table, then uses conditional aggregation to select the min and max frequency names in one row:
with cte as (
select name,
row_number() over (order by count(*) desc) as maxr,
row_number() over (order by count(*)) as minr
from firefighter_certifications
group by name
)
select max(case when minr = 1 then name end) as Min_Name,
max(case when maxr = 1 then name end) as Max_Name
from cte
Postgres doesn't offer "first" and "last" aggregation functions. But there are other, similar methods:
select distinct first_value(name) over (order by cnt desc, name) as name_at_max,
first_value(name) over (order by cnt asc, name) as name_at_min
from (select name, count(*) as cnt
from firefighter_certifications
group by name
) n;
Or without any subquery at all:
select first_value(name) over (order by count(*) desc, name) as name_at_max,
first_value(name) over (order by count(*) asc, name) as name_at_min
from firefighter_certifications
group by name
limit 1;
Here is a db<>fiddle

Order highest to lowest value without using MAX and ORDER BY

I wanted to get the maximum count of a column for which I used Count() and wanted to order the column highest to lowest value without using max or order by desc.
I tried
SELECT COUNT(subject) AS CNT, student
FROM AUTHOR
GROUP BY student AU1
WHERE not exists (SELECT * FROM AUTHOR AU2
WHERE AU2.student <> AU1.student AND AU2.subject > AU1.CNT)
but it doesn't return the desired output.
The desired output is the same as
SELECT COUNT(subject) AS CNT, student
FROM AUTHOR
GROUP BY Student
ORDER BY CNT DESC
but, without the order by desc or MAX.
You can use ORDER BY ASC:
SELECT COUNT(subject) AS CNT, student
FROM AUTHOR
GROUP BY Student
ORDER BY (- CNT) ASC;
If you want the results in a particular order, you need to use ORDER BY. That is one of the rules of using SQL.
OK, so DESC is not allowed and MAX is not allowed.
SELECT
COUNT(subject) AS CNT, student
FROM
AUTHOR
GROUP BY
Student
ORDER BY
-CNT
This does not work in each database software.
An other version:
SELECT * FROM (
SELECT
COUNT(subject) AS CNT, student
FROM
AUTHOR
GROUP BY
Student
) t
ORDER BY
-CNT

Return row with the highest count (like city with most transactions, when there are multiple cities)

I have a table with the following rows:
customer_id
city
transaction_id
date
I want to pull the city which has the highest number of transactions (count(transaction_id)) over a certain time period. A customer can have transactions in multiple cities.
What's the right syntax to achieve this?
UPDATE:
customer A can have 5 transactions in NYC and 10 transactions in Boston. I just want the customer record of the 10 transactions in Boston to be returned. How do I do this and what would have to cities that have the same number of transactions per customer_id?
if you need just top city name count then you can use below approach
select city,count(transaction_id) as cnt
From YourTable
where date=condition --- that you need
group by city
order by cnt desc
limit 1
if you need customerwise highest city name then use row_number()
with cte as
(
select customerid,city,count(*) as cnt
from table_name group by customerid,city
), cte1 as
(
select * ,row_number()over(partition by cusomerid order by cnt desc) rn
from cte
) select * from cte1 where rn=1

Aggregate function like MAX for most common cell in column?

Group by the highest Number in a column worked great with MAX(), but what if I would like to get the cell that is at most common.
As example:
ID
100
250
250
300
200
250
So I would like to group by ID and instead of get the lowest (MIN) or highest (MAX) number, I would like to get the most common one (that would be 250, because there 3x).
Is there an easy way in SQL Server 2012 or am I forced to add a second SELECT where I COUNT(DISTINCT ID) and add that somehow to my first SELECT statement?
You can use dense_rank to return all the id's with the highest counts. This would handle cases when there are ties for the highest counts as well.
select id from
(select id, dense_rank() over(order by count(*) desc) as rnk from tablename group by id) t
where rnk = 1
A simple way to do what you want uses top and order by:
SELECT top 1 id
FROM t
GROUP BY id
ORDER BY COUNT(*) DESC;
This is a statistic called the mode. Getting the mode and max is a bit challenging in SQL Server. I would approach it as:
WITH cte AS (
SELECT t.id, COUNT(*) AS cnt,
row_number() OVER (ORDER BY COUNT(*) DESC) AS seqnum
FROM t
GROUP BY id
)
SELECT MAX(id) AS themax, MAX(CASE WHEN seqnum = 1 THEN id END) AS MODE
FROM cte;