Multiple maximum values - sql

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;

Related

How do I select 1 [oldest] row per group of rows, given multiple groups?

Let's say we have the database table below, called USER_JOBS.
I'd like to write an SQL query that reflects this algorithm:
Divide the whole table in groups of rows defined by a common USER_ID (in the example table, the 2 resulting groups are colored yellow & green)
From each group, select the oldest row (according to SCHEDULE_TIME)
From this example table, the desired SQL query would return these 2 rows:
You can use ranking function (supported in most RDBS):
SELECT *
FROM
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY USER_ID ORDER BY SCHEDULE_TIME DESC) AS RowID
FROM [table]
)
WHERE RowID = 1
WITH Ranked AS (
SELECT
RANK() OVER (PARTITION BY User_ID ORDER BY ScheduleTime DESC) as Ranking,
*
FROM [table_name]
)
SELECT Status, Sob_Type, User_ID, TimeStamp FROM ranking WHERE Ranks = 1;

Select 20 results per every column value

I prepared query that select date from table. In table I got: rank, name, citycode as columns. When I am doing something like that:
select name, citycode
from tab20
where rank <= 20
I got resault of first 20 rows that gets rank <= 20. And Everything would be ok, but I have to show results of first 20 rows per every citystate. Is it possible to create in one query ? I was tryin union etc but it doesn't work well.
Thanks
You would use the row_number() function. Based on the rank that would be:
select t.*
from (select t.*,
row_number() over (partition by citycode order by rank) as seqnum
from tab20 t
) t
where seqnum <= 20;

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

Get second max highest mark and name

Consider a table with two columns: mark and name
I need to get the second highest value, and the name of the second highest value.
You can use ROW_NUMBER(), RANK(), DENSE_RANK() functions in SQL.
But in this case, you'll have to use DENSE_RANK() because there may be a condition where 2 or more students may have scored maximum marks, in such case you can't use ROW_NUMBER() or RANK().
Learn more about this functions click here
SELECT * FROM (
SELECT name, mark, DENSE_RANK() over (order by mark desc) RankNo
FROM tablename
) AS Result
WHERE Result.RankNo = 2
SELECT *
FROM (SELECT name,
mark,
Row_number() over(ORDER BY mark DESC) AS rownums
FROM employees)
WHERE rownums = 2;
SELECT name,mark FROM table ORDER BY mark desc limit 1,1
This code sort all records by mark in descending order. limit 1,1 skips the first result (first 1 = first record) and then returns the next result (second 1 = second record).

Selecting type(s) of account with 2nd maximum number of accounts

Suppose we have an accounts table along with the already given values
I want to find the type of account with second highest number of accounts. In this case, result should be 'FD'. In case their is a contention for second highest count I need all those types in the result.
I'm not getting any idea of how to do it. I've found numerous posts for finding second highest values, say salary, in a table. But not for second highest COUNT.
This can be done using cte's. Get the counts for each type as the first step. Then use dense_rank (to get multiple rows with same counts in case of ties) to get the rank of rows by type based on counts. Finally, select the second ranked row.
with counts as (
select type, count(*) cnt
from yourtable
group by type)
, ranks as (
select type, dense_rank() over(order by cnt desc) rnk
from counts)
select type
from ranks
where rnk = 2;
One option is to use row_number() (or dense_rank(), depending on what "second" means when there are ties):
select a.*
from (select a.type, count(*) as cnt,
row_number() over (order by count(*) desc) as seqnum
from accounta a
group by a.type
) a
where seqnum = 2;
In Oracle 12c+, you can use offset/fetch:
select a.type, count(*) as cnt
from accounta a
group by a.type
order by count(*) desc
offset 1
fetch first 1 row only