Ошибка «подзапрос возвращает более 1 строки». - PullRequest
2 голосов
/ 05 октября 2011

Я новичок в веб-программировании и пытаюсь создать твитт-клон.На данный момент у меня есть 3 таблицы:

пользователи (идентификатор, имя)

  • идентификатор - это автоматически генерируемый идентификатор
  • имяпользователя

твиты (id, content, user_id)

  • id - это автоматически сгенерированный идентификатор
  • content isтекст твита
  • user_id - это идентификатор пользователя, который создал пост

подписчиков (id, user_id, follow_id)

  • id - это автоматически сгенерированный идентификатор
  • user_id - это пользователь, который делает следующее
  • follow_id - это пользователь, за которым следят

ИтакБудучи новичком в SQL, я пытаюсь создать SQL-оператор, который будет возвращать твиты, которые зарегистрированный в данный момент пользователь и все, за кем он следует.

Я пытался использовать это утверждение, которое иногда работает, но в других случаях я получаю сообщение об ошибке «Subquery возвращает более 1 строки».Вот утверждение:

SELECT * FROM tweets 
WHERE user_id IN
((SELECT following_id FROM followers
WHERE user_id = 1),1) ORDER BY date DESC
  • Я привожу здесь 1 в качестве примера, который будет идентификатором текущего пользователя, вошедшего в систему.

У меня нет 'мне не повезло с этим утверждением;любая помощь будет принята с благодарностью!Спасибо.

Ответы [ 3 ]

6 голосов
/ 05 октября 2011

В одном комментарии вы спрашиваете is it generally better to use a subquery or a union.К сожалению, нет простого ответа, просто некоторая информация.


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

SELECT * FROM tweets
INNER JOIN followers ON tweets.user_id = followers.following_id
WHERE followers.user_id = 1

UNION ALL

SELECT * FROM tweets
WHERE user_id = 1

Или ...

SELECT
  *
FROM
  tweets
INNER JOIN
  (SELECT following_id FROM followers WHERE user_id = 1 UNION SELECT 1) AS followers
    ON tweets.user_id = followers.following_id

Или ...

SELECT
  *
FROM
  tweets
WHERE
  EXISTS (SELECT * FROM followers WHERE following_id = tweets.user_id and user_id = 1)
  OR user_id = 1

Есть много, много альтернатив ...


Некоторые разновидности SQL пытаются оптимизировать условие OR и заканчивают проверкой каждой записи в таблице твитов вместо использования INDEX.Это сделает параметр UNION предпочтительным, потому что каждая половина запроса получит выгоду от индекса в поле user_id.

Но вы МОЖЕТЕ фактически реорганизовать этот угловой случай из своего кода в целом: сделайте каждого пользователя подписчикомо себе.Это будет означать, что получение твитов для подписчиков будет, естественно, включать самого пользователя.Будет ли это иметь смысл во всех случаях, зависит от вашего дизайна и других функциональных требований.


Короче говоря, вам лучше всего создать некоторые репрезентативные данные и протестировать варианты.Но я бы не стал сейчас волноваться об этом.Пока вы инкапсулируете этот код в одном месте, вы можете просто выбрать тот, который вам наиболее удобен.Затем, когда остальная часть системы будет взломана, и вы будете гораздо увереннее, что ничего не изменится, вы можете вернуться и оптимизировать , если необходимо .

4 голосов
/ 05 октября 2011
SELECT * 
FROM tweets 
WHERE 
  user_id IN (SELECT following_id FROM followers WHERE user_id = 1)
  OR user_id = 1
ORDER BY date DESC
2 голосов
/ 05 октября 2011

попробуйте

SELECT * FROM tweets WHERE user_id = [YourUser]
UNION
SELECT * FROM tweets WHERE user_id in (SELECT following_id FROM followers WHERE user_id ? [YourUser]

будет работать, даже если у вас нет последователей для вашего пользователя

Есть также решение с объединениями, но на самом деле я спешу. Постараюсь написать запрос, как только у меня будет время. Некоторые другие, вероятно, ответят к тому времени. К сожалению.

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