2015-12-21 2 views
1

Я использую postgreSQL для хранения журналов чата, и у меня есть этот пример схема:SQL с использованием вложенных INSERT INTO?

CREATE TABLE contacts (
    "id" BIGSERIAL PRIMARY KEY, 
    "user" BIGINT NOT NULL, 
    "contact" BIGINT NOT NULL, 
    "savedAs" VARCHAR(36), 
    CONSTRAINT user_fk FOREIGN KEY("user") REFERENCES users("id") ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT contact_fk FOREIGN KEY("contact") REFERENCES users("id") ON DELETE CASCADE ON UPDATE CASCADE, 
    UNIQUE("user", "contact") 
); 

CREATE TABLE messages (
    "id" BIGSERIAL PRIMARY KEY, 
    "contact" BIGINT NOT NULL, 
    "direction" direction_type NOT NULL, 
    "type" message_type default 'text', 
    "body" VARCHAR(1000) NULL, 
    "status" status_type DEFAULT 'none', 
    "time" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    CONSTRAINT contact_fk FOREIGN KEY("contact") REFERENCES contacts("id") ON DELETE CASCADE 
); 

CREATE TABLE last_message (
    "id" BIGSERIAL PRIMARY KEY, 
    "chat" BIGINT NOT NULL UNIQUE, 
    "message" BIGINT NOT NULL, 
    CONSTRAINT message_fk FOREIGN KEY("message") REFERENCES messages("id"), 
    CONSTRAINT chat_fk FOREIGN KEY("chat") REFERENCES contacts("id") ON DELETE CASCADE 
); 

То, что я хочу сделать, это сохранить последнее сообщение для конкретного чата в last_message таблицы. Я думал сделать это так (но не работает):

INSERT INTO last_message (chat, message) VALUES (
    9, 
    (INSERT INTO messages (contact, direction, body) VALUES (9, 'sent', 'hello there') RETURNING id) 
) 

Но я получаю ошибку синтаксиса (syntax error at or near "into"), так вот мои вопросы,

  • , что случилось с вышеизложенным запрос?

  • есть ли лучший способ сделать это? как?

  • есть что-нибудь, что можно улучшить?

+0

Примечание: ваш 'last_message' имеет проблему с естественным ключом. last_message для/от кого? (что, вероятно, должно быть уникальным) – joop

+0

'last_message' хранит последнее сообщение для определенного чата, независимо от того, отправлено или получено. – zola

ответ

0

Используйте КТР:

WITH toinsert as (
     INSERT INTO messages (contact, direction, body) 
      VALUES (9, 'sent', 'hello there') 
      RETURNING id 
    ) 
INSERT INTO last_message (chat, message) 
    SELECT 9, id 
    FROM toinsert; 
-1

Шаг 1

drop table last_message 

Вы можете получить последнее сообщение так:

select contact, direction, body 
from messages 
join 
(select chat, max(time) maxTime 
from messages 
group by chat 
) temp on messages.chat = temp.chat 
and time = maxTime 

Вы можете создать вид или что-то с этой логикой, какими бы ни были ваши требования.