#mysql #sql
#mysql #sql
Вопрос:
Я смоделировал небольшую базу данных для упрощения объяснения:
CREATE TABLE bands (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(120) NULL,
PRIMARY KEY(id)
)
TYPE=InnoDB;
CREATE TABLE albums (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
band_id INTEGER UNSIGNED NOT NULL,
album_name VARCHAR(120) NULL,
rating INTEGER UNSIGNED NULL,
insertion_date TIMESTAMP NULL,
PRIMARY KEY(id),
INDEX albums_FKIndex1(band_id),
FOREIGN KEY(band_id)
REFERENCES bands(id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)
TYPE=InnoDB;
Теперь, делая вид, что у нас уже есть несколько групп и много альбомов, зарегистрированных в соответствующих таблицах, я хочу выбрать ТОЛЬКО последний вставленный альбом из каждой зарегистрированной группы.
PS: Я должен использовать поле «album.insertion_date», чтобы определить, какой альбом вставлен последним.
Комментарии:
1. Может быть, вы можете вставить куда-нибудь ( gist.github.com ) небольшой дамп ваших вставок? Мне нужно выполнить проверку запроса.
2. Вы отметили вопрос как Postgresql, но ваш SQL четко показывает MySQL. Что вы используете?
3. Я использую postgres. Кажется, я экспортировал SQL в неправильном формате
Ответ №1:
Попробуйте объединить две таблицы и выполнить фильтрацию по insertion_date и band:
SELECT al.*
FROM albums al
INNER JOIN bands b ON al.band_id=b.id
WHERE al.insertion_date=(
SELECT max(insertion_date)
FROM albums
WHERE band_id=b.id
)
Комментарии:
1. ОШИБКА 1054 (42S22): неизвестный столбец ‘b.band_id’ в предложении ‘where’
2. Doliveras побеждает! поздравляю, и с хорошим временем выполнения (даже с базой данных, заполненной 18980 реестрами)
Ответ №2:
Попробуйте этот:
select b.name, a.album_name, a.isertion_date
from bands b, albums a
where a.band_id = b.id
and a.insertion_date = (select max(a1.insertion_date) from albums a1 where a1.band_id = b.id)
Комментарии:
1. Который выводит последний альбом из определенной группы, я хочу получить последний альбом из каждой группы в одном SQL. Я думаю, что задал неправильный вопрос, лол
Ответ №3:
Учитывая, что у вас есть идентификаторы альбомов, которые должны быть AUTO_INCREMENT
и возможность того, что они insertion_date
должны быть NULL
(поскольку это значение по умолчанию), использование insertion_date для определения результатов — не самая разумная вещь, но … вот и все:
SELECT DISTINCT band, last_album, insertion_date
FROM (
SELECT bands.name AS band, albums.album_name AS last_album, albums.insertion_date
FROM bands
JOIN albums ON bands.id=albums.band_id
ORDER BY albums.insertion_date DESC
) t1
GROUP BY band;
Комментарии:
1. имя_альбома отсутствует в предложении group by, поэтому mysql может свободно возвращать любое имя_альбома в пределах того же диапазона, это может быть не тот, у которого max insertion_date
2. Это не проблема при использовании
ORDER BY
, но в любом случае это было неправильно … итак, я просто отредактировал его.3. Об использовании даты вставки для выбора последнего реестра: К сожалению, я не был ответственным за миграцию базы данных. Реестры новой базы данных не были вставлены в том же порядке, что и реестры из старой базы данных. Это отстой, но это нужно было сделать.
4. Я не могу внести исправления сейчас, поскольку мне нужно сохранить совместимость со старым приложением, которое будет деактивировано через несколько месяцев. Поэтому я должен подождать, прежде чем запускать какой-либо сценарий нормализации.