create table dt
(
id varchar(20),
user_id int,
name varchar(20),
td DATE,
amount float
);
INSERT INTO dt VALUES('blah',1, 'Rodeo', '2018-01-20', 10.12);
INSERT INTO dt VALUES('blahblah',1, 'Rodeo', '2019-01-01', 40.44);
INSERT INTO dt VALUES('sas',2, 'Janice', '2018-02-05', 18.18);
INSERT INTO dt VALUES('dsdcd',3, 'Sam', '2019-01-26', 16.13);
INSERT INTO dt VALUES('sdc',2, 'Janice', '2018-02-01', 12.19);
INSERT INTO dt VALUES('scsc',2, 'Janice', '2017-12-06', 5.10);
+----------+---------+--------+------------+--------+
| id | user_id | name | td | amount |
+----------+---------+--------+------------+--------+
| blah | 1 | Rodeo | 2018-01-20 | 10.12 |
| blahblah | 1 | Rodeo | 2019-01-01 | 40.44 |
| sas | 2 | Janice | 2018-02-05 | 18.18 |
| dsdcd | 3 | Sam | 2019-01-26 | 16.13 |
| sdc | 2 | Janice | 2018-02-01 | 12.19 |
| scsc | 2 | Janice | 2017-12-06 | 5.1 |
+----------+---------+--------+------------+--------+
对于上表,我如何获得此输出。我可以通过开窗功能来实现,但是不确定如何通过相关子查询来实现。感谢任何帮助!
输出 基本上是用户的首次交易金额与其最近的交易金额之差。如果用户只有一笔交易,则差值为0
User_id name amount
1 Rodeo 30.32 [40.44(latest trans) - 10.12 (min trans)]
3 Sam 0
2 Janice 13.08 [18.18 (latest trans) - 5.1 (min trans)]
答案 0 :(得分:1)
这类似于SQL select only rows with max value on a column,但是您需要做两次:一次是最早的行,一次是最新的行。
SELECT t1.user_id, t1.name, t1.amount - t2.amount ASA amount
FROM (
SELECT dt1.user_id, dt1.name, dt1.amount
FROM dt AS dt1
JOIN (
SELECT user_id, name, MAX(td) AS maxdate
FROM dt
GROUP BY user_id, name) AS dt2
ON dt1.user_id = dt2.user_id AND dt1.name = dt2.name AND dt1.td = dt2.maxdate
) AS t1
JOIN (
SELECT dt1.user_id, dt1.name, dt1.amount
FROM dt AS dt1
JOIN (
SELECT user_id, name, MIN(td) AS mindate
FROM dt
GROUP BY user_id, name) AS dt2
ON dt1.user_id = dt2.user_id AND dt1.name = dt2.name AND dt1.td = dt2.mindate
) AS t2
ON t1.user_id = t2.user_id AND t1.name = t2.name
答案 1 :(得分:1)
具有2个子查询以获取最新和最早的金额:
select distinct t.user_id, t.name,
(select amount from dt
where user_id = t.user_id
order by td desc limit 1
)
-
(select amount from dt
where user_id = t.user_id
order by td limit 1
) amount
from dt t
请参见demo。
或者:
select t.user_id, t.name,
max(t.latest * t.amount) - max(t.earliest * t.amount) amount
from (
select d.user_id, d.name, d.amount,
d.td = g.earliestdate earliest, d.td = g.latestdate latest
from dt d inner join (
select user_id, min(td) earliestdate, max(td) latestdate
from dt
group by user_id
) g on d.user_id = g.user_id and d.td in (earliestdate, latestdate)
) t
group by t.user_id, t.name
请参见demo。
结果:
| user_id | name | amount |
| ------- | ------ | ------ |
| 1 | Rodeo | 30.32 |
| 2 | Janice | 13.08 |
| 3 | Sam | 0 |
答案 2 :(得分:1)
使用相关子查询的方法:
查询
SELECT user_id,
name,
Round(Coalesce ((SELECT t1.amount
FROM dt t1
WHERE t1.user_id = dt.user_id
ORDER BY t1.td DESC
LIMIT 1) - (SELECT t2.amount
FROM dt t2
WHERE t2.user_id = dt.user_id
ORDER BY t2.td ASC
LIMIT 1), 0), 2) AS amount
FROM dt
GROUP BY user_id,
name;
| user_id | name | amount |
| ------- | ------ | ------ |
| 1 | Rodeo | 30.32 |
| 2 | Janice | 13.08 |
| 3 | Sam | 0 |
答案 3 :(得分:0)
您也可以尝试
Select t3.user_id, t3.name, max(t3.new_amount) FROM (
Select t1.user_id, t2.name, (t1.amount - t2.amount) as new_amount
FROM dt t1
INNER JOIN dt t2
ON t1.user_id=t2.user_id
Order by t1.user_id ASC, t1.td DESC, t2.user_id ASC, t2.td ASC
) as t3
group by t3.user_id,t3.name;