add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
version()
8.0.25
id email
1 111@xyz.com
2 222@xyz.com
3 333@xyz.com
4 444@xyz.com
5 555@xyz.com
6 666@xyz.com
lh_id user_id login_dt
1 1 2011-01-11 00:00:00
2 1 2011-02-11 00:00:00
3 1 2011-03-11 00:00:00
4 2 2012-01-12 00:00:00
5 2 2012-02-12 00:00:00
6 2 2012-03-12 00:00:00
7 3 2013-01-13 00:00:00
8 3 2013-02-13 00:00:00
9 3 2013-03-13 00:00:00
10 4 2014-01-14 00:00:00
11 4 2014-02-14 00:00:00
12 4 2014-03-14 00:00:00
13 5 2015-01-15 00:00:00
14 5 2015-02-15 00:00:00
15 5 2015-03-15 00:00:00
rn lh_id id ldt
1 3 1 2011-03-11 00:00:00
2 2 1 2011-02-11 00:00:00
3 1 1 2011-01-11 00:00:00
1 6 2 2012-03-12 00:00:00
2 5 2 2012-02-12 00:00:00
3 4 2 2012-01-12 00:00:00
1 9 3 2013-03-13 00:00:00
2 8 3 2013-02-13 00:00:00
3 7 3 2013-01-13 00:00:00
1 12 4 2014-03-14 00:00:00
2 11 4 2014-02-14 00:00:00
3 10 4 2014-01-14 00:00:00
1 15 5 2015-03-15 00:00:00
2 14 5 2015-02-15 00:00:00
3 13 5 2015-01-15 00:00:00
id email lh_id ldt
1 111@xyz.com 3 2011-03-11 00:00:00
2 222@xyz.com 6 2012-03-12 00:00:00
3 333@xyz.com 9 2013-03-13 00:00:00
4 444@xyz.com 12 2014-03-14 00:00:00
5 555@xyz.com 15 2015-03-15 00:00:00
id email Last login
1 111@xyz.com 2011-03-11 00:00:00
2 222@xyz.com 2012-03-12 00:00:00
3 333@xyz.com 2013-03-13 00:00:00
4 444@xyz.com 2014-03-14 00:00:00
5 555@xyz.com 2015-03-15 00:00:00
6 666@xyz.com null
id email rn lh_id luid ldt
6 666@xyz.com 1 null null null
5 555@xyz.com 1 15 5 2015-03-15 00:00:00
5 555@xyz.com 2 14 5 2015-02-15 00:00:00
5 555@xyz.com 3 13 5 2015-01-15 00:00:00
4 444@xyz.com 1 12 4 2014-03-14 00:00:00
4 444@xyz.com 2 11 4 2014-02-14 00:00:00
4 444@xyz.com 3 10 4 2014-01-14 00:00:00
3 333@xyz.com 1 9 3 2013-03-13 00:00:00
3 333@xyz.com 2 8 3 2013-02-13 00:00:00
3 333@xyz.com 3 7 3 2013-01-13 00:00:00
2 222@xyz.com 1 6 2 2012-03-12 00:00:00
2 222@xyz.com 2 5 2 2012-02-12 00:00:00
2 222@xyz.com 3 4 2 2012-01-12 00:00:00
1 111@xyz.com 1 3 1 2011-03-11 00:00:00
1 111@xyz.com 2 2 1 2011-02-11 00:00:00
1 111@xyz.com 3 1 1 2011-01-11 00:00:00
id email rn lh_id luid ldt
1 111@xyz.com 1 3 1 2011-03-11 00:00:00
2 222@xyz.com 1 6 2 2012-03-12 00:00:00
3 333@xyz.com 1 9 3 2013-03-13 00:00:00
4 444@xyz.com 1 12 4 2014-03-14 00:00:00
5 555@xyz.com 1 15 5 2015-03-15 00:00:00
6 666@xyz.com 1 null null null
EXPLAIN
-> Sort: u.id (actual time=0.172..0.246 rows=5 loops=1)
    -> Stream results (cost=0.50 rows=0) (actual time=0.135..0.160 rows=5 loops=1)
        -> Nested loop inner join (cost=0.50 rows=0) (actual time=0.132..0.150 rows=5 loops=1)
            -> Index lookup on tab using <auto_key0> (rn=1) (actual time=0.002..0.004 rows=5 loops=1)
                -> Materialize (cost=0.00..0.00 rows=0) (actual time=0.120..0.123 rows=5 loops=1)
                    -> Window aggregate: row_number() OVER (PARTITION BY lh.user_id ORDER BY lh.login_dt desc ) (actual time=0.046..0.088 rows=15 loops=1)
                        -> Sort: lh.user_id, lh.login_dt DESC (cost=1.75 rows=15) (actual time=0.041..0.045 rows=15 loops=1)
                            -> Index scan on lh using lh_user_dt_uq (actual time=0.013..0.025 rows=15 loops=1)
            -> Single-row index lookup on u using PRIMARY (id=tab.id) (cost=0.30 rows=1) (actual time=0.005..0.005 rows=1 loops=5)
EXPLAIN
-> Sort: u.id, u.email (actual time=0.140..0.141 rows=6 loops=1)
    -> Table scan on <temporary> (actual time=0.001..0.002 rows=6 loops=1)
        -> Aggregate using temporary table (actual time=0.127..0.129 rows=6 loops=1)
            -> Nested loop left join (cost=2.95 rows=6) (actual time=0.024..0.060 rows=16 loops=1)
                -> Table scan on u (cost=0.85 rows=6) (actual time=0.014..0.018 rows=6 loops=1)
                -> Index lookup on lh using lh_user_dt_uq (user_id=u.id) (cost=0.27 rows=1) (actual time=0.005..0.006 rows=2 loops=6)
EXPLAIN
-> Sort: tab.id (actual time=0.011..0.012 rows=6 loops=1)
    -> Index lookup on tab using <auto_key0> (rn=1) (actual time=0.002..0.003 rows=6 loops=1)
        -> Materialize (cost=0.00..0.00 rows=0) (actual time=0.189..0.191 rows=6 loops=1)
            -> Window aggregate: row_number() OVER (PARTITION BY lh.user_id ORDER BY lh.login_dt desc ) (actual time=0.108..0.136 rows=16 loops=1)
                -> Sort: lh.user_id, lh.login_dt DESC (actual time=0.105..0.110 rows=16 loops=1)
                    -> Stream results (cost=2.95 rows=6) (actual time=0.030..0.084 rows=16 loops=1)
                        -> Nested loop left join (cost=2.95 rows=6) (actual time=0.024..0.059 rows=16 loops=1)
                            -> Table scan on u (cost=0.85 rows=6) (actual time=0.015..0.018 rows=6 loops=1)
                            -> Index lookup on lh using lh_user_dt_uq (user_id=u.id) (cost=0.27 rows=1) (actual time=0.004..0.006 rows=2 loops=6)
id email lh_id ldt
1 111@xyz.com 3 2011-03-11 00:00:00
2 222@xyz.com 6 2012-03-12 00:00:00
3 333@xyz.com 9 2013-03-13 00:00:00
4 444@xyz.com 12 2014-03-14 00:00:00
5 555@xyz.com 15 2015-03-15 00:00:00
id email Last login
1 111@xyz.com 2011-03-11 00:00:00
2 222@xyz.com 2012-03-12 00:00:00
3 333@xyz.com 2013-03-13 00:00:00
4 444@xyz.com 2014-03-14 00:00:00
5 555@xyz.com 2015-03-15 00:00:00
6 666@xyz.com null
id email rn lh_id luid ldt
1 111@xyz.com 1 3 1 2011-03-11 00:00:00
2 222@xyz.com 1 6 2 2012-03-12 00:00:00
3 333@xyz.com 1 9 3 2013-03-13 00:00:00
4 444@xyz.com 1 12 4 2014-03-14 00:00:00
5 555@xyz.com 1 15 5 2015-03-15 00:00:00
6 666@xyz.com 1 null null null
Query_ID Duration Query
1 0.00069825 SELECT u.*, tab.lh_id, tab.ldt
FROM user u
JOIN
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY lh.user_id ORDER BY lh.login_dt DESC) AS rn,
    lh_id,
    lh.user_id AS id,
    lh.login_dt AS ldt
  FROM login_history lh
) tab
ON u.id = tab.id
WHERE tab.rn = 1
ORDER BY u.id
2 0.00073325 SELECT u.id, u.email, MAX(lh.login_dt) AS "Last login"
FROM user u
LEFT JOIN login_history lh
  ON u.id = lh.user_id
GROUP BY u.id, u.email
ORDER BY u.id
3 0.00079925 SELECT * FROM
(
  SELECT
    u.id,
    u.email,
    ROW_NUMBER() OVER (PARTITION BY lh.user_id ORDER BY lh.login_dt DESC) AS rn,
    lh.lh_id,
    lh.user_id AS luid,
    lh.login_dt AS ldt
  FROM user u
  LEFT JOIN login_history lh
  ON u.id = lh.user_id
) AS tab
WHERE tab.rn = 1
ORDER BY tab.id
id email lh_id ldt
5 555@xyz.com 15 2015-03-15 00:00:00
5 555@xyz.com 14 2015-02-15 00:00:00
4 444@xyz.com 12 2014-03-14 00:00:00
4 444@xyz.com 11 2014-02-14 00:00:00
3 333@xyz.com 9 2013-03-13 00:00:00
3 333@xyz.com 8 2013-02-13 00:00:00
2 222@xyz.com 6 2012-03-12 00:00:00
2 222@xyz.com 5 2012-02-12 00:00:00
1 111@xyz.com 3 2011-03-11 00:00:00
1 111@xyz.com 2 2011-02-11 00:00:00
id email rn lh_id luid ldt
6 666@xyz.com 1 null null null
5 555@xyz.com 1 15 5 2015-03-15 00:00:00
5 555@xyz.com 2 14 5 2015-02-15 00:00:00
4 444@xyz.com 1 12 4 2014-03-14 00:00:00
4 444@xyz.com 2 11 4 2014-02-14 00:00:00
3 333@xyz.com 1 9 3 2013-03-13 00:00:00
3 333@xyz.com 2 8 3 2013-02-13 00:00:00
2 222@xyz.com 1 6 2 2012-03-12 00:00:00
2 222@xyz.com 2 5 2 2012-02-12 00:00:00
1 111@xyz.com 1 3 1 2011-03-11 00:00:00
1 111@xyz.com 2 2 1 2011-02-11 00:00:00