MySQL Query: выбор строк связанных таблиц и перехват "большего" набора данных - PullRequest
0 голосов
/ 10 мая 2011

Я пытаюсь выяснить, как построить запрос, который удовлетворяет следующим критериям:

У меня есть две таблицы.Таблица a хранит список авторов.А таблица b хранит список книг.У меня есть таблица ссылок c, которая отображает каждого автора на одну или несколько книг.Естественно, книга может иметь более одного автора.Учитывая имя (давайте назовем имя = "Дуглас Адамс") автора, я знаю, что если я сделаю

SELECT * FROM linktable
    INNER JOIN a ON linktable.a_id = a.id
    INNER JOIN b ON linktable.p_id = b.id
WHERE a.name = 'Douglas Adams';

, я получу все книги, которые были написаны Дугласом Адамсом.Допустим, у Дугласа Адамса иногда были «соавторы».Как мне их получить?

Мне нужен список, который как-то выглядит так:

Douglas Adams, The Hitchhiker's Guide to the Galaxy, maybe more details...
Douglas Adams, Book_2, maybe more details...
Coauthor_1, Book_2, same Details as in "Douglas Adams, Book_2, maybe more details..."

Это выполнимо?


Я создал 3 таблицы,какую карту я хочу сохранить и что я хочу получить.

2 таблицы хранения:

CREATE TABLE `a` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name_UNIQUE` (`name`),
  KEY `name_INDEX` (`name`),
  FULLTEXT KEY `name_FULLTEXT` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=932723 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

CREATE TABLE `b` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `title_fulltext` (`title`)
) ENGINE=MyISAM AUTO_INCREMENT=1617432

и одна третья таблица, которая связывает две таблицы выше.

CREATE TABLE `linktable` (
  `a_id` int(11) NOT NULL,
  `b_id` int(11) NOT NULL,
  KEY `a_id_INDEX` (`a_id`),
  KEY `b_id_INDEX` (`b_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Ответы [ 2 ]

2 голосов
/ 10 мая 2011
SELECT a2.Name, b.title
    FROM a
        INNER JOIN linktable lt
            ON a.id = lt.a_id
        INNER JOIN b
            ON lt.b_id = b.id
        INNER JOIN linktable lt2
            ON lt.b_id = lt2.b_id
        INNER JOIN a a2
            ON lt2.a_id = a2.id
    WHERE a.Name = 'Douglas Adams'
    ORDER BY b.title,
             /* Case Statement so Douglas Adams sorts before other authors */
             CASE WHEN a2.Name = 'Douglas Adams' THEN 1 ELSE 2 END,
             a2.Name
1 голос
/ 10 мая 2011

Это должно работать:

SELECT * FROM b where b.id in(SELECT c.b_id 
FROM a,c
WHERE a.author = "Douglas Adams"
AND a.id= c.a_id)

Редактировать, Альтернатива:

SELECT * 
FROM A,B,
(SELECT c.b_id, c.a_id
    FROM a,c
    WHERE a.author = "Douglas Adams"
    AND a.id= c.a_id) X
WHERE b.id = x.b_id
    AND a.id = x.a_id
...