簡體   English   中英

SQL在分組依據期間選擇另一個具有最大值的列

[英]SQL select another column with max during group by

我有一個sqlite數據庫,正在執行此查詢。

SELECT
  thread.id as id,
  thread.title as title,
  post.posted as posted,
  user.username as username
FROM post
INNER JOIN thread ON post.thread_id = thread.id
INNER JOIN user ON post.user_id = user.id
ORDER BY posted desc;

這給了我以下幾行

5|Creating Thread|2017-07-23 08:05:15.730725|zrbecker
5|Creating Thread|2017-07-23 08:05:07.881327|zrbecker
4|This is a new thread|2017-07-23 05:14:08.513643|zrbecker
4|This is a new thread|2017-07-23 05:13:40.172866|admin
1|First Thread!|2017-07-23 05:10:43.772543|zrbecker
3|Here is a post|2017-07-23 04:58:10.999243|ralph
3|Here is a post|2017-07-23 04:52:49.060482|admin
3|Here is a post|2017-07-23 04:52:30.497092|admin
3|Here is a post|2017-07-23 04:50:53.800177|admin
2|Another Thread|2017-07-23 02:21:46.544810|ralph
1|First Thread!|2017-07-23 02:17:46.544810|ralph
1|First Thread!|2017-07-23 02:16:46.544810|admin

我想做一個“分組依據”,在這里我按thread.id分組,我想要一個last_posted和first_posted列作為日期。 但我也希望last_username和first_username知道發布該帖子的用戶。

這是我的第一次嘗試。

SELECT
  thread.id as id,
  thread.title as title,
  count(post.id) as number_posts,
  max(post.posted) as last_posted,
  user.username as last_username,
  min(post.posted) as first_posted,
  user.username as first_username
FROM post
INNER JOIN thread ON post.thread_id = thread.id
INNER JOIN user ON post.user_id = user.id
GROUP BY thread_id
ORDER BY last_posted desc;

我完全沒有理由期望它能夠正常工作。 好像我需要一個輸出兩個列的max函數。 不只是我正在盡力而為的專欄。

有什么幫助嗎?

編輯:這是我的sqlite3數據庫的.dump

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE thread (
        id INTEGER NOT NULL,
        title VARCHAR(80),
        PRIMARY KEY (id)
);
INSERT INTO thread VALUES(1,'First Thread!');
INSERT INTO thread VALUES(2,'Another Thread');
INSERT INTO thread VALUES(3,'Here is a post');
INSERT INTO thread VALUES(4,'This is a new thread');
INSERT INTO thread VALUES(5,'Creating Thread');
CREATE TABLE user (
        id INTEGER NOT NULL,
        username VARCHAR(30) NOT NULL,
        password VARCHAR(50) NOT NULL,
        PRIMARY KEY (id),
        UNIQUE (username)
);
INSERT INTO user VALUES(1,'admin','test123');
INSERT INTO user VALUES(2,'ralph','password123');
INSERT INTO user VALUES(3,'zrbecker','helloworld');
CREATE TABLE post (
        id INTEGER NOT NULL,
        user_id INTEGER,
        thread_id INTEGER,
        message TEXT NOT NULL,
        posted DATETIME,
        PRIMARY KEY (id),
        FOREIGN KEY(user_id) REFERENCES user (id),
        FOREIGN KEY(thread_id) REFERENCES thread (id)
);
INSERT INTO post VALUES(1,1,1,'First Post!','2017-07-23 02:16:46.544810');
INSERT INTO post VALUES(2,2,1,'Second post!','2017-07-23 02:17:46.544810');
INSERT INTO post VALUES(3,2,2,'Another post','2017-07-23 02:21:46.544810');
INSERT INTO post VALUES(4,1,3,'Lorem Ipsum ','2017-07-23 04:50:53.800177');
INSERT INTO post VALUES(5,1,3,'test test','2017-07-23 04:52:30.497092');
INSERT INTO post VALUES(6,1,3,'test trest test','2017-07-23 04:52:49.060482');
INSERT INTO post VALUES(7,2,3,'Hello There','2017-07-23 04:58:10.999243');
INSERT INTO post VALUES(8,3,1,'hello','2017-07-23 05:10:43.772543');
INSERT INTO post VALUES(9,1,4,'This is my message','2017-07-23 05:13:40.172866');
INSERT INTO post VALUES(10,3,4,'hello','2017-07-23 05:14:08.513643');
INSERT INTO post VALUES(11,3,5,'This is a thread','2017-07-23 08:05:07.881327');
INSERT INTO post VALUES(12,3,5,'New post','2017-07-23 08:05:15.730725');
COMMIT;

我最終想到了一個似乎有效的SQL查詢。 雖然看起來很復雜。 希望有更簡單的東西。

這是查詢:

SELECT
  thread.id AS id,
  thread.title AS title,
  thread.post_count AS post_count,
  thread.last_posted AS last_posted,
  last_user.username AS last_username,
  thread.first_posted AS first_posted,
  first_user.username AS first_username
FROM (
  SELECT
    thread.id AS id,
    thread.title AS title,
    count(post.id) AS post_count,
    max(post.posted) AS last_posted,
    min(post.posted) AS first_posted
  FROM thread
  INNER JOIN post ON post.thread_id = thread.id
  GROUP BY thread.id
) AS thread
INNER JOIN post AS last_post
  ON last_post.thread_id = thread.id
  AND last_post.posted = thread.last_posted
INNER JOIN post AS first_post
  ON first_post.thread_id = thread.id
  AND first_post.posted = thread.first_posted
INNER JOIN user AS last_user ON last_post.user_id = last_user.id
INNER JOIN user AS first_user ON first_post.user_id = first_user.id
ORDER BY last_posted DESC;

所需的輸出如下所示:

5|Creating Thread|2|2017-07-23 08:05:15.730725|zrbecker|2017-07-23 08:05:07.881327|zrbecker
4|This is a new thread|2|2017-07-23 05:14:08.513643|zrbecker|2017-07-23 05:13:40.172866|admin
1|First Thread!|3|2017-07-23 05:10:43.772543|zrbecker|2017-07-23 02:16:46.544810|admin
3|Here is a post|4|2017-07-23 04:58:10.999243|ralph|2017-07-23 04:50:53.800177|admin
2|Another Thread|1|2017-07-23 02:21:46.544810|ralph|2017-07-23 02:21:46.544810|ralph

另一個編輯:我的最終目標是制作一個SQLAlchemy表達式,該表達式將為我完成此任務。 當我不知道如何使用ORM時,我決定嘗試提出一個可以指導我的原始SQL查詢。 任何可以使我朝這個方向發展的建議都很好。

謝謝。

請嘗試以下查詢

with postData as(
SELECT
post.*
,row_number() over (partition by  post.thread_id order by post.posted desc) descRowNumber
,row_number() over (partition by  post.thread_id order by post.posted ) ascRowNumber
FROM post
)
SELECT thread.id AS id,
thread.title AS title,
last_posted.posted AS last_postedDate,
last_user.username AS last_username,
first_posted.posted AS first_postedDate,
first_user.username AS first_username 
from
thread left join
  (select id,thread_id from postData where ascRowNumber=1) first_posted on first_posted.thread_id=thread.id
left join  
  (select id,thread_id from postData where descRowNumber=1) last_posted on last_posted.thread_id=thread.id
left JOIN [user] AS first_user ON first_posted.user_id = first_user.id
left JOIN [user] AS last_user ON last_posted.user_id = last_user.id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM