每天为每个用户获取最后一次注销(MAX(),GROUP BY)[postgresql]
Get last logout for every user for every day (MAX(), GROUP BY) [postgresql]
我有很多用户的多次注销。我想获取每个用户每天的最后一次注销。
SELECT t_logouts.log_id,
t_users.last_name || ' ' || t_users.first_name,
t_logouts.log_date,
MAX(t_logouts.log_time),
(DATE_PART('hour', '18:00:00'::time - t_logouts.log_time ) * 60 +
DATE_PART('minute', '18:00:00'::time - t_logouts.log_time )) / 60
FROM t_logouts
LEFT JOIN t_users
ON t_users.user_id = t_logouts.user_id
GROUP BY DATE(t_logouts.log_date), t_users.user_id
ORDER BY t_logouts.log_date DESC, t_logouts.log_time ASC ;
抛出错误:
LINE 1: SELECT t_logouts.log_id,
^
SQL state: 42803
Character: 8
据我了解,多重聚合存在一些问题。
我试过使用本手册:
https://www.postgresqltutorial.com/postgresql-group-by/
https://www.postgresqltutorial.com/postgresql-max-function/
我正在尝试使用的表。
CREATE TABLE t_users (
user_id SERIAL PRIMARY KEY,
nickname name UNIQUE not null check (length(nickname) < 64),
first_name VARCHAR NOT NULL check (length(first_name) < 64),
last_name VARCHAR NOT NULL check (length(last_name) < 64),
email VARCHAR DEFAULT NULL check (email ~* '^.+@.+\..+$' )
);
CREATE TABLE t_logins (
log_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id)
REFERENCES t_users (user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
log_date DATE NOT NULL,
log_time TIME NOT NULL
);
CREATE TABLE t_logouts (
log_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id)
REFERENCES t_users (user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
log_date DATE NOT NULL,
log_time TIME NOT NULL
);
这通常使用 Postgres 中的 distinct on ()
完成:
SELECT distinct on (t_users.user_id)
t_logouts.log_id,
t_users.last_name || ' ' || t_users.first_name,
t_logouts.log_date,
t_logouts.log_time,
extract(epoch from '18:00:00'::time - t_logouts.log_time) / 3600
FROM t_logouts
LEFT JOIN t_users ON t_users.user_id = t_logouts.user_id
ORDER BY t_users.user_id, t_logouts.log_date DESC;
我有很多用户的多次注销。我想获取每个用户每天的最后一次注销。
SELECT t_logouts.log_id,
t_users.last_name || ' ' || t_users.first_name,
t_logouts.log_date,
MAX(t_logouts.log_time),
(DATE_PART('hour', '18:00:00'::time - t_logouts.log_time ) * 60 +
DATE_PART('minute', '18:00:00'::time - t_logouts.log_time )) / 60
FROM t_logouts
LEFT JOIN t_users
ON t_users.user_id = t_logouts.user_id
GROUP BY DATE(t_logouts.log_date), t_users.user_id
ORDER BY t_logouts.log_date DESC, t_logouts.log_time ASC ;
抛出错误:
LINE 1: SELECT t_logouts.log_id,
^
SQL state: 42803
Character: 8
据我了解,多重聚合存在一些问题。 我试过使用本手册: https://www.postgresqltutorial.com/postgresql-group-by/ https://www.postgresqltutorial.com/postgresql-max-function/
我正在尝试使用的表。
CREATE TABLE t_users (
user_id SERIAL PRIMARY KEY,
nickname name UNIQUE not null check (length(nickname) < 64),
first_name VARCHAR NOT NULL check (length(first_name) < 64),
last_name VARCHAR NOT NULL check (length(last_name) < 64),
email VARCHAR DEFAULT NULL check (email ~* '^.+@.+\..+$' )
);
CREATE TABLE t_logins (
log_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id)
REFERENCES t_users (user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
log_date DATE NOT NULL,
log_time TIME NOT NULL
);
CREATE TABLE t_logouts (
log_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id)
REFERENCES t_users (user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
log_date DATE NOT NULL,
log_time TIME NOT NULL
);
这通常使用 Postgres 中的 distinct on ()
完成:
SELECT distinct on (t_users.user_id)
t_logouts.log_id,
t_users.last_name || ' ' || t_users.first_name,
t_logouts.log_date,
t_logouts.log_time,
extract(epoch from '18:00:00'::time - t_logouts.log_time) / 3600
FROM t_logouts
LEFT JOIN t_users ON t_users.user_id = t_logouts.user_id
ORDER BY t_users.user_id, t_logouts.log_date DESC;