Почему этот запрос возвращает больше значений, чем должен

#postgresql

#postgresql

Вопрос:

 SELECT username, user_status
FROM users
JOIN relationships ON users.user_id = relationships.user_two_id
WHERE relationships.user_one_id = $1
   OR relationships.user_two_id = $1
  AND relationships.relationship_status = 1
  

Рассматриваемый запрос приведен выше; то, что я пытаюсь сделать, это использовать идентификатор пользователя
проверьте, являются ли пользователи друзьями или нет, основываясь на ‘1’, который присутствовал бы, если бы они были друзьями.

ОЖИДАЕТСЯ:
вернет статус пользователей, если они друзья

АКТУАЛЬНО:
возвращает дополнительные дубликаты пользователя, для которого я выполняю запрос — поэтому, если мое имя пользователя bob и я выполняю этот запрос, я вижу bob несколько раз, когда я не должен был видеть его даже один раз.

Примеры таблиц:

 CREATE TABLE users (
user_id bigserial UNIQUE PRIMARY KEY,
email VARCHAR(30) UNIQUE,
password VARCHAR(70),
username VARCHAR(30)UNIQUE,
dob  INTEGER,
country VARCHAR(30),
province VARCHAR(30),
city VARCHAR(30),
date TIMESTAMP
);

CREATE TABLE relationships(
record bigserial UNIQUE PRIMARY KEY,
user_one_id bigserial REFERENCES users(user_id),
user_two_id bigserial REFERENCES users(user_id),
relationship_status INTEGER,
date TIMESTAMP WITH TIME zone
);
  

Комментарии:

1. В исходной таблице отношений для user_two_id есть «повторяющиеся» строки. Итак, почему запрос выбирает «неожиданные» строки? Что ж, посмотрите на данные ..

2. Может быть полезно учитывать, что WHERE relationships.user_one_id = $1 OR relationships.user_two_id = $1 AND relationships.relationship_status = 1 анализируется как WHERE relationships.user_one_id = $1 OR (relationships.user_two_id = $1 AND relationships.relationship_status = 1) (обратите внимание на скобки; И имеет более высокий приоритет, чем ИЛИ).

3. Postgres или MySQL? Почему вы отметили оба?

4. @user2864740 Я удалил повторяющиеся строки из таблицы перед публикацией этого вопроса, в настоящее время повторяющихся связей нет. Есть ли у вас какие-либо рекомендации, как сделать этот запрос более надежным или как предотвратить это?

5. @ErwinBrandstetter большинство серверных разработчиков в какой-то момент имеют дело с mysql или, скорее, с той же логикой, что и довольно распространенная, таким образом, раскрывая мой вопрос большему количеству глаз. Запрос, который я выполняю, находится в Postgres

Ответ №1:

Был однострочным и довольно встроенным при запуске; ВЫБЕРИТЕ ОТДЕЛЬНОЕ имя пользователя, user_status ….