Добавить второй (условный) результат из второй таблицы в запрос SQL - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть две таблицы в базе данных. Один хранит имена / данные пользователей с индексом ID; другие хранят статьи, которые они написали, в которых просто хранится идентификатор пользователя в качестве ссылки (поле author ). Пока все просто. Я могу легко запросить список статей и включить в запрос запрос имени и статуса пользователя:

SELECT a.name, a.status, s.* FROM articles s, author a WHERE s.author=a.id

Проблема возникает, когда я иногда получаю кредит второго автора, на который ссылается поле author2 . До сих пор я выполнял, как мне кажется, очень неэффективный второй запрос, когда я перебираю результаты, просто чтобы получить имя и статус второго автора из таблицы (псевдокод):

while ( fetch a row ) {
    if (author2 != 0) {
        query("SELECT name, status FROM author WHERE id=author2") }
    etc. }

Хотя это работало нормально в PHP / MySQL (даже если неуклюже), я вынужден перейти на PHP7 / PDO и хотел бы получить преимущества небуферизованных запросов, поэтому этот вложенный запрос не будет работать. Очевидно, что одним простым решением было бы PDO-> fetchALL () сначала получить все результаты, прежде чем итерировать все строки результатов в foreach l oop и выполнять эти дополнительные запросы для каждой строки.

Но это было бы гораздо более эффективно получить второй бит данных, каким-то образом включенный в основной запрос, извлекая из таблицы автора с использованием второго идентификатора ( author2 ), а также основного идентификатора, так что name2 и поля status2 добавлены в каждую строку. Я просто не могу понять, как это сделать ...

Следует отметить, что хотя поле ИД основного автора ВСЕГДА ненулевое, поле author2 будет содержать ноль, если второго ИД нет, и В таблице авторов отсутствует идентификатор автора 0, поэтому любое решение должно обрабатывать идентификатор author2, равный 0, предоставляя пустые строки или что-то в этих полях, а не выдавая ошибку. (Или, что гораздо менее элегантно, фиктивный идентификатор автора 0 с нулевыми данными можно добавить в таблицу авторов, я полагаю.)

Может кто-нибудь предложить пересмотренный исходный запрос, который может избежать таких вторичных запросов?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

Никогда не используйте запятые в предложении FROM. Всегда используйте правильный, явный, стандартный JOIN синтаксис.

Для запроса используйте LEFT JOIN:

SELECT s.*, a1.name, a1.status, a2.name, a2.status
FROM articles s LEFT JOIN
     author a1
     ON s.author = a1.id LEFT JOIN
     author a2
     ON s.author2 = a2.id
0 голосов
/ 07 февраля 2020

Ответ Гордона Линоффа выглядит так, как вам нужно.

Я бы добавил это как комментарий, но это слишком длинное сообщение ...

У меня просто вопрос / комментарий относительно нормализации базы данных. Был ли когда-нибудь случай, когда есть автор? Если так, то у вас, вероятно, должна быть таблица ArticleAuthor. Поскольку вы все равно перестраиваете код, это может быть улучшением для рассмотрения.

Я не знаю имен и типов данных информации, которую вы храните, так что это примитивный пример структуры, которую я бы предложил.

Table Article
ArticleID
ArticleData...

Table Author
AuthorID
AuthorName
AuthorStatus

Table ArticleAuthor
ArticleID
AuthorID

Если статус зависит от комбинации статей автора, то AuthorStatus будет перемещен в таблицу ArticleAuthor следующим образом.

Table ArticleAuthor
ArticleID
AuthorID
Status
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...