2010-07-15 3 views
1

Мне нужна твоя помощь в создании предложения SQL. Я не могу окутать голову.sql join in join?

В базе данных у меня есть четыре таблицы - файлы, папки, папки и ссылки.

У меня много файлов. Один из них называется «myFile.txt».

У меня есть много папок. «myFile.txt» находится в некоторых из них. Первая папка, в которой она появляется, называется «firstFolder».

У меня есть много ссылок на многие папки. Первая ссылка на «firstFolder» называется «firstLink».

Структура данных для примера будет:

// files 
Id: 10 
Name: "myFile.txt" 

// folders 
Id: 20 
Name: "firstFolder" 

// folder_files (join table) 
Id: 30 
Folder_Id: 20 (meaning "firstFolder") 
File_Id: 1 (meaning "myFile.txt") 

// links 
Id: 40 
Name: "firstLink" 
Folder_Id: 20 (meaning "firstFolder") 

ПЕРВЫЙ ВОПРОС: Как получить запись для «Myfile.txt» и имя и идентификатор «firstLink» (первое звено), запрос на файл Id = 10, на основе самого низкого идентификатора папки и ссылки?

ВТОРОЙ ВОПРОС: Как получить запись для «myFile.txt» И имя и идентификатор «firstLink» (первая ссылка), запрашивая все файлы на основе самого низкого идентификатора папки и ссылки ?

введите другой способ - как получить первую ссылку на первую папку, содержащую «myFile.txt»?

В результате в записи, которая выглядит следующим образом:

Id: 10 
Name: "myFile.txt" 
LinkId: 40 
LinkName: "firstLink" 

Спасибо!

+0

Под «первым», вы имеете в виду с самым низким ID? – Wrikken

+2

Я добавил тег 'great-n-per-group'. Попробуйте нажать на этот тег, и вы увидите много других случаев эквивалентной проблемы с решениями. Попробуйте прочитать некоторые из них, а затем вернитесь и отредактируйте свой вопрос с помощью того, что вы пробовали (всегда лучше делать домашнее задание самостоятельно). Извините, мне пришлось подрезать тэг 'subselect', потому что существует ограничение на пять тегов. Но вам не обязательно нужен подзапрос, чтобы решить эту проблему. –

+0

@Wrikken - да, самый низкий Id. @ bill - спасибо за редактирование, т. К. Я достаточно новичок в SQL, что я действительно не вижу, как относится к группе наибольшая-n-на-группу? Я думаю, что я просто присоединяюсь ...? Я вырыл вокруг этого форума и сети за час до публикации. – user110218

ответ

2

Вы должны попытаться подумать о том, как вы хотите, чтобы ваш результирующий набор выглядел. SQL предназначен для описания наборов результатов. Если вы можете написать гипотетический результирующий набор, вам может понадобиться легче написать SQL, который отобразит этот набор результатов.

Мне было трудно понять, что вы ищете, но я уверен, что это довольно прямолинейная проблема. Я бы мог помочь вам легче, если бы вы могли более четко описать результаты, хотя вам больше не понадобится моя помощь!

Например (идти с вами оригинальный схемы) Q1 & Q2:

files.Id, files.Name, links.Id, links.Name (4 колонки)

Q1:

SELECT 
    files.Id, files.Name, links.Id, links.Name 
FROM 
    files, links 
INNER JOIN 
    folder_files 
    ON files.Id = folder_files.File_Id 
INNER JOIN 
    links 
    ON links.Id = folder_files.Folder_Id 
WHERE 
    files.Id = 10 
ORDER BY 
    folder_files.File_Id ASC, links.Id ASC 
LIMIT 1;

(JOIN со столом папок не обязательно)

Q2:

Изменение и ASC в DESC

+0

Спасибо - я подумал об этом вскоре после публикации, но он не появился в моем редактировании. Это сейчас. – user110218

+0

Вот и все! Два внутренних соединения! Это то, чего мне не хватало. Благодаря! – user110218

1

Это выбирает все ссылки на идентификатор файла 10:

select links.id, links.name 
from files 
left join folder_files on files.id = folder_files.file_id 
left join folders on folder_files.folder_id = folders.id 
left join links on links.folder_id = folders.id 
where files.id=10; 

Изменение где положение, добавить ограничение или любые другие вещи, которые вы хотите. Это должно быть просто изменить это.

+0

Извините, я сформулировал свой вопрос неправильно. Я хочу получить имя и идентификатор ссылки вместе с данными записи для файла. Поэтому они не являются отдельными запросами. – user110218

0

Я хотел бы попробовать это:

select f.* 
     , l.Id as LinkId 
     , l.Name as LinkName, 
    from Link l 
     inner join Folder_Files ff on ff.Folder_Id = l.Folder_Id 
     inner join Files f on f.Id = ff.File_Id 
    where f.Id = 10 

Результирующая к:

Id | Name  | LinkId | LinkName 
10 | myFile.txt | 40  | firstLink 

Является ли это то, что вы хотите?

0

Принимая во внимание:

  • более папок в файл
  • более ссылки на папку
  • принимая наименьшую папку ID для связи, и наименьшую ссылку ID для папки

С помощью of: mysql: group by ID, get highest priority per each ID

Ответ на ВСЕ файлы в таблице файлов (перейти на Joh nB для одного файла, это было бы быстрее):

SELECT file_id, file_name, link_id, link_name FROM (
SELECT file_id, file_name, link_id, link_name, 
    @r := CASE WHEN @prev_file_id = file_id 
        THEN @rn + 1 
        ELSE 1 
       END AS r, 
    @prev_file_id := file_id 
FROM (
    SELECT 
     f.id as file_id, f.name as file_name, l.id as link_id, l.name as link_name 
    FROM files f 
    JOIN folder_files ff 
    ON ff.file_id = f.id 
    JOIN links l 
    ON l.folder_id = ff.folder_id 
    ORDER BY ff.folder_id, l.id -- first folder first, first link to first folder second 
) derived1, 
(SELECT @prev_file_id := NULL,@r:=0) vars 
) derived2 
WHERE r = 1;