левое соединение со специальным условием в правой таблице
Вопрос
не знаю, возможно ли это..Я использую схему SQLite3:
Документы CREATE TABLE (целочисленный идентификатор первичного ключа, строка имени);
CREATE TABLE revs (целочисленный идентификатор первичного ключа, целое число doc_id, целое число);
Я хочу выбрать каждое задание, объединенное только с одной из его редакций, с наибольшим номером.Как я могу этого добиться?Прямо сейчас я делаю левое соединение и получаю все, а затем фильтрую это в приложении, но это отстой..
(кстати, не могли бы вы предложить мне хорошую и простую вводную книгу по базам данных и как они работают И, может быть, что -то в SQL тоже ..) Спасибо!
Решение
Не уверен, поддерживает ли это ваш движок, но обычно в ANSI SQL вы делаете что-то вроде этого:
SELECT docs.*
,revs.*
FROM docs
INNER /* LEFT works here also if you don't have revs */ JOIN revs
ON docs.id = revs.doc_id
AND revs.number IN (
SELECT MAX(number)
FROM revs
WHERE doc_id = docs.id
)
Существует несколько способов написания эквивалентных запросов с использованием общих табличных выражений, коррелированных агрегатных подзапросов и т. д.
Другие советы
попробуй это
Select * From docs d
Join revs r
On r.doc_id = d.id
Where r.number =
(Select Max(number ) from revs
Where Doc_Id = d.Id)
или, если вам нужны документы без версий (возможно ли это?)
Select * From docs d
Left Join revs r
On r.doc_id = d.id
And r.number =
(Select Max(number ) from revs
Where Doc_Id = d.Id)
select d.*, r.max_number
from docs d
left outer join (
select doc_id, max(number) as max_number
from revs
group by doc_id
) r on d.id = r.doc_id
Проектирование базы данных: Проектирование баз данных для простых смертных от Эрнандес
SQL: Практическое руководство по SQL
Если хотите заморочить голову, то любая книга по SQL Джо Селко.
Вот очень хороший список книг по проектированию баз данных.
Если каждое задание имеет версии (например, начиная с версии 0), я бы использовал тот же подход, что и OrbMan, но с внутренним соединением.(Если вы уверены, что ищете совпадение 1 к 1.почему бы не сообщить об этом и SQL?)
select d.*, r.max_number from docs d inner join ( select doc_id, max(number) as max_number from revs group by doc_id ) r on d.id = r.doc_id
Я бы порекомендовал «Разумный подход к проектированию баз данных» как отличное введение в передовые методы проектирования.(Я немного предвзят.Я написал это.Но эй, на данный момент средний обзор на Amazon составляет 5 звезд, ни один из отзывов не был написан мной, друзьями или родственниками.)