1

I am using postgreSQL for storing chat logs, and I have this sample schema:

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
);

What I want to do, is store the last message for a particular chat in the last_message table. I was thinking of doing it like this(but not working):

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

But I get a syntax error(syntax error at or near "into"), so here are my questions,

  • what is wrong with the above query?

  • is there a better a way to do this? how?

  • is there anything that can be improved?

3
  • Note: your last_message has a natural key problem. last_message for/from whom ? (that would probably need to be unique) Commented Dec 21, 2015 at 17:15
  • last_message stores the last message for a particular chat whether sent or received doesn't matter. Commented Dec 21, 2015 at 17:37
  • Possible duplicate of Postgres insert value from insert in other table Commented Mar 8, 2019 at 20:59

2 Answers 2

1

Use a CTE:

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;
Sign up to request clarification or add additional context in comments.

Comments

-1

Step 1

drop table last_message

You can get the last message like this:

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

You can create a view or whatever with this logic, whatever your requirements happent to be.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.