Итак, я пытался показать всем авторам с большинством книг, написанных с использованием, и я попробовал это:

select *
from writer as a,(
SELECT writer_id,count(writer_id) as posts
FROM blog
GROUP BY writer_id
) as b WHERE a.id = b.writer_id 
GROUP BY writer_id
HAVING posts>=max(posts);

Но когда я выполняю его, он возвращает всю таблицу, а не только те, которые содержат большинство книг. Почему здесь не работает? Я думаю, что что-то упустил. Если я заменяю Max ( сообщения ) с фактическим числом максимальных сообщений из моего примера таблицы она работает.

Я использую примеры таблиц из этого вопроса: Вопрос

0
butterflyflyaway 8 Дек 2019 в 02:49
Примечания: (1) больше не следует использовать соединения, разделенные запятыми. В 1992 году в стандартном SQL они были сделаны избыточными. (2) Если вы хотите подсчитать записи, используйте COUNT(*). COUNT(<expression>) используется для подсчета ненулевых вхождений. С count(writer_id) похоже, что writer_id может быть нулевым, и вы хотите исключить такие строки из подсчета.
 – 
Thorsten Kettner
8 Дек 2019 в 03:08
Проблема с вашим запросом: Каждому писателю вы присоединяетесь к их количеству блогов. Затем вы группируете по писателю, что на самом деле ничего не делает, так как у вас уже есть одна строка для каждого писателя. Затем вы сравниваете количество блогов писателя с максимальным количеством блогов писателя. Вы берете максимум числа, а это просто само число. Писателю с десятью блогами вы говорите: верните эту строку, если 10 = 10. Писателю с пятью блогами вы говорите: верните эту строку, если 5 = 5. Вы возвращаете все строки.
 – 
Thorsten Kettner
8 Дек 2019 в 03:16

2 ответа

Чтобы получить писателя с большинством книг, вы можете просто order by и limit:

select w.name, count(*) no_of_books
from writer w 
join blog b on w.id = b.writer_id
group by w.id
order by no_of_books desc
limit 1

Если есть верхние связи (то есть несколько авторов с большинством книг), и вы хотите получить их все, решение состоит в том, чтобы фильтровать с помощью предложения having:

select w.name, count(*) no_of_books
from writer w 
join blog b on w.id = b.writer_id
group by w.id
having count(*) = (
    select count(*) from blog group by writer_id order by count(*) desc limit 1
)
order by w.name
1
GMB 8 Дек 2019 в 03:06

Вы можете сделать это с помощью оконной функции rank():

select w.*, t.counter 
from writer w inner join (
  select writer_id, count(*) counter,
    rank() over (order by count(*) desc) rn
  from blog
  group by writer_id      
) t on t.writer_id = w.id
where t.rn = 1

Этот код также возвращает связи, если они существуют.
См. демонстрацию.
Полученные результаты:

| id  | name     | counter |
| --- | -------- | ------- |
| 3   | Writer C | 4       |
0
forpas 8 Дек 2019 в 12:44