如何查找重复记录,而不是使用聚合函数和分组依据?
How to find repetitive record, not using aggregate functions and group by?
db里有singers和songs表,我们要通过不使用聚合函数和关键字分组的方式来找出谁拥有最多的歌曲数。
tables in turkish
Table 翻译
song(sarkino, name, tour, duration, composerno, author no)
singer(singer, name, type, birthDate, birthPlace)
album(albumno, name, year, price, singer, stock quantity)
Song in the album(albumno, song, order)
composer(composcino, name, tour)
author(author, name)
问题原文:
enter image description here
问题已翻译:
Solve the author numbers of the authors who wrote the most lyrics, as
we did in the classroom (in the example in the presentation) without
using the aggregate function or group by.
正如 Ergest 提到的,非常标准的方法是使用 GROUP BY
和 COUNT
。不过好吧,今天你的老师喜欢挑战。
GarethD 的替代解决方案(完全符合要求)
我想在我的回答中回顾一下 GarethD 评论,功劳全归于他。
If the instructor considers COUNT(*) an aggregate function even when used in a windowed function, this wouldn't be a viable solution. If the only requirement is to get the singer with the most songs, then an alternative is to use ROW_NUMBER() which is almost certainly not an aggregate function by anyone's definition
SELECT s.name,
ROW_NUMBER() OVER (PARTITION BY s.id ORDER BY Songs.id) AS number_of_songs
FROM singers AS s
JOIN Songs
ON Songs.singer_id = s.id
ORDER BY number_of_songs DESC
LIMIT 1
name
number_of_songs
Linkin Park
5
我的原始解决方案使用 COUNT OVER PARTITION BY
您需要使用 COUNT
的高级版本,结合 OVER (PARTITION BY singer_id)
,与 COUNT
GROUP BY singer_id
具有相同的效果。这将统计指定分区 singer_id
上的所有歌曲记录,即总共 singer_id.
的歌曲记录
由于您添加了一堆不同 SQL 数据库类型的标签,我将选择 Postgres 来编写示例演示片段。不要担心,因为 COUNT(*) OVER PARTITION
语法对于每个 SQL 数据库
可能都是相同的
WITH singers(id, name) AS (
VALUES(1, 'Lady Gaga'),
(2, 'Elton John'),
(3, 'Linkin Park')
),
songs(id, name, singer_id)
AS (
VALUES(1, 'Born This Way', 1),
(2, 'Rocket Man', 2),
(3, 'Numb', 3),
(4, 'In The End', 3),
(5, 'Papercut', 3),
(6, 'Can You Feel The Love Tonight?', 2),
(7, 'Tiny Dancer', 2),
(8, 'Your Song', 2),
(9, 'Waiting For The End', 3),
(10, 'Forgotten', 3)
)
SELECT singers.*, song_count.number_of_songs
FROM singers
JOIN
(SELECT DISTINCT singer_id, COUNT(*) OVER (PARTITION BY singer_id) as number_of_songs
FROM songs) song_count
ON singers.id = song_count.singer_id
ORDER BY song_count.number_of_songs DESC;
id
name
number_of_songs
3
Linkin Park
5
2
Elton John
4
1
Lady Gaga
1
SELECT
子句中的DISTINCT
用于删除singer_id
number_of_songs
select
的重复记录
SELECT singer_id, COUNT(*) OVER (PARTITION BY singer_id) as number_of_songs
FROM songs;
singer_id
number_of_songs
1
1
2
4
2
4
2
4
2
4
3
5
3
5
3
5
3
5
3
5
看看这个 db fiddle here
db里有singers和songs表,我们要通过不使用聚合函数和关键字分组的方式来找出谁拥有最多的歌曲数。
tables in turkish
Table 翻译
song(sarkino, name, tour, duration, composerno, author no)
singer(singer, name, type, birthDate, birthPlace)
album(albumno, name, year, price, singer, stock quantity)
Song in the album(albumno, song, order)
composer(composcino, name, tour)
author(author, name)
问题原文:
enter image description here
问题已翻译:
Solve the author numbers of the authors who wrote the most lyrics, as we did in the classroom (in the example in the presentation) without using the aggregate function or group by.
正如 Ergest 提到的,非常标准的方法是使用 GROUP BY
和 COUNT
。不过好吧,今天你的老师喜欢挑战。
GarethD 的替代解决方案(完全符合要求)
我想在我的回答中回顾一下 GarethD 评论,功劳全归于他。
If the instructor considers COUNT(*) an aggregate function even when used in a windowed function, this wouldn't be a viable solution. If the only requirement is to get the singer with the most songs, then an alternative is to use ROW_NUMBER() which is almost certainly not an aggregate function by anyone's definition
SELECT s.name,
ROW_NUMBER() OVER (PARTITION BY s.id ORDER BY Songs.id) AS number_of_songs
FROM singers AS s
JOIN Songs
ON Songs.singer_id = s.id
ORDER BY number_of_songs DESC
LIMIT 1
name | number_of_songs |
---|---|
Linkin Park | 5 |
我的原始解决方案使用 COUNT OVER PARTITION BY
您需要使用 COUNT
的高级版本,结合 OVER (PARTITION BY singer_id)
,与 COUNT
GROUP BY singer_id
具有相同的效果。这将统计指定分区 singer_id
上的所有歌曲记录,即总共 singer_id.
由于您添加了一堆不同 SQL 数据库类型的标签,我将选择 Postgres 来编写示例演示片段。不要担心,因为 COUNT(*) OVER PARTITION
语法对于每个 SQL 数据库
WITH singers(id, name) AS (
VALUES(1, 'Lady Gaga'),
(2, 'Elton John'),
(3, 'Linkin Park')
),
songs(id, name, singer_id)
AS (
VALUES(1, 'Born This Way', 1),
(2, 'Rocket Man', 2),
(3, 'Numb', 3),
(4, 'In The End', 3),
(5, 'Papercut', 3),
(6, 'Can You Feel The Love Tonight?', 2),
(7, 'Tiny Dancer', 2),
(8, 'Your Song', 2),
(9, 'Waiting For The End', 3),
(10, 'Forgotten', 3)
)
SELECT singers.*, song_count.number_of_songs
FROM singers
JOIN
(SELECT DISTINCT singer_id, COUNT(*) OVER (PARTITION BY singer_id) as number_of_songs
FROM songs) song_count
ON singers.id = song_count.singer_id
ORDER BY song_count.number_of_songs DESC;
id | name | number_of_songs |
---|---|---|
3 | Linkin Park | 5 |
2 | Elton John | 4 |
1 | Lady Gaga | 1 |
SELECT
子句中的DISTINCT
用于删除singer_id
number_of_songs
select
SELECT singer_id, COUNT(*) OVER (PARTITION BY singer_id) as number_of_songs
FROM songs;
singer_id | number_of_songs |
---|---|
1 | 1 |
2 | 4 |
2 | 4 |
2 | 4 |
2 | 4 |
3 | 5 |
3 | 5 |
3 | 5 |
3 | 5 |
3 | 5 |
看看这个 db fiddle here