2015-06-10 3 views
2

Мне нужна помощь для SQL-запроса. Поскольку я новичок в этом домене, я не мог объяснить Google, что я пытаюсь сделать, я еще не нашел подходящего ответа. Возможно ли это с моими таблицами?«Отрицательный» запрос SQL (postgres)

Я хочу получать все темы (id, name), которые не являются моими нитями и которые уже не проголосовали за меня. (Т.е. Threads я могу голосовать)

База данных выглядит следующим образом:

Threads 
+----+-------------+---------+ 
| id | thread_name | user_id | 
+----+-------------+---------+ 
| 1 | Soccer  |  1 | 
| 2 | Running  |  1 | 
| 3 | Swimming |  2 | 
+----+-------------+---------+ 

User 
+----+--------+ 
| id | name | 
+----+--------+ 
| 1 | Marcel | 
| 2 | Marc | 
| 3 | Susy | 
+----+--------+ 

Votes 
+----+-----------+---------+ 
| id | thread_id | user_id | 
+----+-----------+---------+ 
| 1 |   1 |  3 | 
| 2 |   1 |  2 | 
| 3 |   2 |  3 | 
+----+-----------+---------+ 

Пример:

  • Если пользователь 1 делает запрос, он должен получить нить 3, потому что это не его и он еще не голосовал.
  • Пользователь 2 должен получать нить 2
  • пользователя 4 должен получать все темы

Я пробовал:

SELECT DISTINCT t.id, name FROM threads as t 
LEFT JOIN votes as v ON v.thread_id = t.id 
WHERE (v.user_id != USER_ID OR v.user_id IS NULL) 
AND t.user_id != USER_ID 

Я использую Sequelize (Node.js ОРМ). pgAdmin дает мне следующую (упрощенную) схему: надеюсь, что это поможет:

-- Table: "threads" 
-- DROP TABLE "threads"; 

CREATE TABLE "threads" 
(
    id serial NOT NULL, 
    name character varying(255), 
    "createdAt" timestamp with time zone NOT NULL, 
    "updatedAt" timestamp with time zone NOT NULL, 
    "user_id" integer, 
    CONSTRAINT "threads_pkey" PRIMARY KEY (id), 
    CONSTRAINT "threads_user_id_fkey" FOREIGN KEY ("user_id") 
     REFERENCES "users" (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE "threads" 
    OWNER TO postgres; 

-- Table: "votes" 
-- DROP TABLE "votes"; 

CREATE TABLE "votes" 
(
    id serial NOT NULL, 
    "createdAt" timestamp with time zone NOT NULL, 
    "updatedAt" timestamp with time zone NOT NULL, 
    "user_id" integer, 
    "thread_id" integer, 
    CONSTRAINT "votes_pkey" PRIMARY KEY (id), 
    CONSTRAINT "votes_thread_id_fkey" FOREIGN KEY ("thread_id") 
     REFERENCES "threads" (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL, 
    CONSTRAINT "votes_user_id_fkey" FOREIGN KEY ("user_id") 
     REFERENCES "users" (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE "votes" 
    OWNER TO postgres; 


-- Table: "users" 
-- DROP TABLE "users"; 

CREATE TABLE "users" 
(
    id serial NOT NULL, 
    username character varying(255), 
    "createdAt" timestamp with time zone NOT NULL, 
    "updatedAt" timestamp with time zone NOT NULL, 
    CONSTRAINT "users_pkey" PRIMARY KEY (id) 
) 
WITH (
    OIDS=FALSE 
); 
    ALTER TABLE "users" 
     OWNER TO postgres; 

Спасибо.

+0

MySQL или PostgreSQL? – Houari

+0

@Houari PostgreSQL –

+0

Хорошо, и что вы попробовали? – Houari

ответ

1

Это должно решить вашу проблему.

select t.id from threads as t where t.user_id != USER_ID and t.id not in 
(select v.thread_id from votes as v where v.user_id = USER_ID); 
+0

спасибо. Похоже, он работает таким образом. Никогда не думал об использовании двух операторов select. Возможно ли это с одним? –

+0

@MarcelSchulze Я не могу сказать точно. Я думаю, что немного отредактировать ваш запрос, но он не смог сделать. Поэтому я переписываю это так. Я надеюсь, что это приведет вас вперед в вашей задаче, что является вопросом в конце;) – shivams

Смежные вопросы