Вот еще один способ, который, я считаю, эквивалентен подходу factor(..)
:
> df <- data.frame(let=letters[1:5], num=1:5)
> subdf <- df[df$num <= 3, ]
> subdf$let <- subdf$let[ , drop=TRUE]
> levels(subdf$let)
[1] "a" "b" "c"
Как некоторые люди упоминали в комментариях, у вас есть проблема с вашими двойными кавычками, и они объяснили, как вы должны справиться с этим.
Я покажу вам, как решить проблему с SQL, которая у вас возникла. Я создам образец таблицы messages
.
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY ,
sender_id BIGINT ,
reciever_id BIGINT,
message TEXT,
sent_at TIMESTAMP
);
Теперь давайте заполним эту таблицу некоторыми данными:
INSERT INTO messages (sender_id, reciever_id, message, sent_at) VALUES
(1,3,'User 1 to user 3 1 hour ago', '2017-07-10 15:00:00'),
(1,3,'User 1 to user 3 last','2017-07-10 16:00:00'),
(2,3,'User 2 to user 3 2 hours ago','2017-07-10 14:00:00'),
(2,3,'User 2 to user 3 last','2017-07-10 16:00:00');
Теперь давайте скажем, что мы хотим найти все последние сообщения (по sender_id), которые были отправлены пользователю с помощью [ 114] 3.
Таким образом, исходя из входных данных, результат должен возвращать 2 сообщения:
Этого можно достичь с помощью следующего запроса:
WITH sender_last_message_time AS (
SELECT sender_id, MAX(sent_at) sent_at FROM messages
WHERE reciever_id = 3
GROUP BY sender_id )
SELECT * FROM messages m
JOIN sender_last_message_time r ON m.sender_id = r.sender_id AND r.sent_at = m.sent_at;
Объяснение:
I создайте sender_last_message_time
CTE , который содержит время последнего сообщения (отправленное sender_id) для каждого отправителя. Когда у меня есть sender_id и время последнего сообщения для этого sender_id, я просто соединяю данные с таблицей messages
, чтобы получить сообщения.
Двойные кавычки в Postgresql могут считаться вредными из-за , как работают двойные кавычки . Их следует использовать только тогда, когда есть вероятность путаницы с ключевым словом.
"tm.senderId"
не означает senderId
в псевдониме tm
. Поскольку .
цитируется, это означает в точности идентификатор tm.senderId
. Постгрес ищет столбец tm.senderId
в таблице direct_messages
и не находит его.
Вместо этого вы должны написать "tm"."senderId"
осторожно, чтобы указать таблицу / псевдоним и столбец отдельно.
test=# create table direct_messages ( senderId integer );
CREATE TABLE
test=# \d direct_messages
Table "public.direct_messages"
Column | Type | Collation | Nullable | Default
----------+---------+-----------+----------+---------
senderid | integer | | |
( Обратите внимание, что даже описание таблицы "public.direct_messages"
вводит в заблуждение. )
И оно будет делать то же самое для таблиц и столбцов без кавычек в запросах.
test=# select * from direct_messages tm where tm.sEnDerID is not null;
senderid
----------
(0 rows)
Но если вы процитируете их, он будет искать точное совпадение.
test=# select * from direct_messages tm where tm."sEnDerID" is not null;
ERROR: column tm.sEnDerID does not exist
LINE 1: select * from direct_messages tm where tm."sEnDerID" is not ...
test=# select * from direct_messages tm where tm."senderId" is not null;
ERROR: column tm.senderId does not exist
LINE 1: select * from direct_messages tm where tm."senderId" is not ...
^
HINT: Perhaps you meant to reference the column "tm.senderid".
test=# select * from direct_messages tm where tm."senderid" is not null;
senderid
----------
(0 rows)
В вашем запросе нет двусмысленных имен столбцов, поэтому удалите двойные кавычки.
SELECT *
FROM direct_messages tm
LEFT JOIN users tu ON tm.senderId = tu.id
WHERE tm.createdAt
ORDER BY created_at DESC
LIMIT 1;
(Дополнительное примечание: смешивать смешивание camelCase createdAt
и snake_case created_at
. Выберите один стиль для проекта и придерживайтесь его.)