Как стать автором
Обновить

Комментарии 18

Если я правильно посчитал в уме, в п.7 SQL выдаст не количество музыкантов в жанре, а количество имён музыкантов в жанре. Там count(m.name), а не count(m.id)… к тому же считаются не уникальные значения, а все (без distinct). Проверьте на всякий случай, может, я и неправ O:-)


В любом случае, спасибо, прокручивать такие штуки в голове — отличная разминка поутру и способ проснуться!

Да, вы все правильно заметили, однако по условию задачи у нас имена музыкантов уникальные поэтому в данном случае разницы нет. Я поправлю запросы в коде. Спасибо.

Разве уникальные? Mary и Kate встречаются много раз… рад помочь.
Да, музыканты уникальные, они конечно могут повторяться несколько раз в таблице, но при нормализации БД мы их группируем по имени. Такое условие данной задачи.
Что-то мне кажется в п.10 не решается вопрос «все исполнители, которые не выпустили альбомы в 2020 году»
Код
select distinct m.name
from musicians as m
left join albums_musicians as am on m.id = am.musician_id
left join albums as a on a.id = am.album_id
where not a.year = 2020
order by m.name

выдаст музыкантов, у которых есть альбомы не в 2020, независимо от того, выпускали они альбом в 2020 или нет
Вы абсолютно правы. Я не учел, что могут быть авторы, которые выпустили альбом и в 2020 и в других годах. Таких по условию задачи надо убирать.
Проблема могла проявиться раньше, если бы мои демо-данные предусматривали такой вариант. Статью исправил, код на репо обновил вместе с данными, спасибо большое за внимательность!
Увидел. Тогда я предложу немного другое решение:
select distinct m.name
from musicians as m
left join albums_musicians as am on m.id = am.musician_id
left join albums as a on (a.id = am.album_id) and (a.year = 2020)
where a.id is null
order by m.name
Спасибо, но ваш вариант работает также как и мой первоначальный. В таблице есть музыкант Peter который выпустил два альбома — в 2020 и 2016 годах. Вот он попадает в выборку, хотя не должен. Честно говоря даже не знаю как можно исправить ваш запрос.
Буду премного благодарен, если покажете как обойтись без вложенных запросов в данном случае.
нет, он попадет в эту выборку со своим альбомом 2020 года
select distinct m.name
from musicians as m
left join albums_musicians as am on m.id = am.musician_id
left join albums as a on (a.id = am.album_id) and (a.year = 2020)

и тут его «настигнет» условие
where a.id is null

которое он не преодолеет и в итоге его не будет
Ну я не просто так написал — проверил и увидел что он присутствует в выборке.
image

В тоже время мой запрос вот так выполняется:
image

Может есть разница на какой СУБД исполнять этот код (вот это выражение is null оно входит в стандарт SQL92)? У меня если что свежий Postgres.
признаю свою вину, средняя таблица albums_musicians все испортила
и пока «сходу» без подзапроса не вышло:
select distinct m.name
from musicians as m
left join 
  (select am.musician_id, a.year, a.id
  from albums_musicians as am 
  left join albums as a on (a.id = am.album_id)) as temptable
on (m.id = temptable.musician_id) and (temptable.year = 2020)
where temptable.id is null
order by m.name

а вот более извращенное, но почему бы и нет:
select m.name
from musicians as m
left join albums_musicians as am on m.id = am.musician_id
left join albums as a on (a.id = am.album_id) 
group by m.name, m.id
having count(case when a.year = 2020 then a.id end)=0
order by m.name

Ух-ты, так работает, благодарю. Но я честно говоря еще не сталкивался с такими выражениями case… end
А я вот почему-то к ORM так и не привык… Пытался использовать и Алхимию, и PonyORM (для теж же Postgres), но старый-добрый SQL как-то ближе и понятней все равно (лично мне). Возможно, просо не дозрел до таких абстракций :) Но если честно, мне кажется, что код, содержащий «сырые» SQL запросы лучше читается и понятнее, чем с ORM, для тех, кто знаком с SQL.
Мне также. Но еще мне кажется, что дело именно в «кто знаком с SQL»
Неизвестно как пошло бы дело, если бы я вместо SQL учил бы какой-нибудь LINQ и только его.
Дело привычки, мне кажется.
Вот да! Вместо понятного и отлаженного за несколько десятков лет SQL вылезает какой-то новый кривоватый язык, на котором в простых ситуациях запрос чуть короче, а в сложных ситуациях получается намного длиннее и корявее, чем в SQL. Ну и появляется лишняя точка отказа.
Поклонники ORM: попробуйте нас троих переубедить.
Согласен, SQL читается гораздо легче. А написать ORM запросы совсем без знания SQL не получится. Вот и выходит что ORM будут использовать те кто знает SQL, а нужна ли собаке пятая нога?
Однако следует заметить что ORM подход позволяет получить сразу объект без парсинга результатов запросов через SQL, то есть в теории он позволяет сделать код лаконичнее. Но тут как говорится дело вкуса. А о вкусах не спорят.
Расширяя свой предыдущий комментарий, добавлю, что, как мне кажется, ORM предпочитают «пуристы» от python, т.е. те, кто в принципе не терпят вкрапления других языков в код. Весь смысл ORM — «питонизация» всего кода (в данном случае — для python, но есть, конечно, и для других ЯП). Для тех, кто (как я сам) вполне нормально относится к смеси ЯП в разумных пределах и на благо эффективности и удобочитаемости, ORM не нужны как таковые. В мою бытность программирования на C/C++ я сам не чурался оптимизации за счет ASM вставок. Но это выглядит диковато и требует определенного знакомства с низкоуровневыми ЯП. SQL же сам по себе — высокоуровневый и весьма эффективный язык, который вполне нормально выглядит вместе с python.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.