![](/img/trans.png)
[英]MySQL best way to select first, second and last value in each group
[英]Select first and last row for each group and take the column value difference in MySQL?
我有以下表結構
象征 | 日期 | 價格 |
---|---|---|
蘋果 | 2021-02-21 | 10 |
特斯拉 | 2021-02-21 | 800 |
亞馬遜 | 2021-02-21 | 90 |
蘋果 | 2021-02-20 | 17 |
特斯拉 | 2021-02-20 | 900 |
亞馬遜 | 2021-02-20 | 105 |
蘋果 | 2021-02-19 | 5 |
特斯拉 | 2021-02-19 | 960 |
亞馬遜 | 2021-02-19 | 80 |
…… | …… | …… |
問題:現在,對於給定的日期范圍date >= '2021-02-19' and date <= '2021-02-21'
我希望找到該日期范圍的價格差異。 也就是執行查詢后,下面是我想要的output,
象征 | PRICE_CHANGE |
---|---|
蘋果 | 5 |
特斯拉 | -160 |
亞馬遜 | 10 |
…… | …… |
我的嘗試:
(SELECT symbol, "date"
FROM public.ticks
where "date" >= '2021-02-19 11:30:00' and "date" <= '2021-02-19 12:30:00'
order by "date" desc) t group by t.symbol;
我無法弄清楚如何通過一個組來確定 go 並選擇該組的第一行和最后一行並減去價格。
任何幫助是極大的贊賞!
使用 MySQL-8.0/MariaDB-10.2+ window function:
SELECT symbol,
LAST - FIRST AS price_change
FROM
(SELECT DISTINCT symbol,
first_value(price) OVER w AS FIRST,
last_value(price) OVER w AS LAST
FROM ticks WINDOW w AS (PARTITION BY symbol
ORDER BY date
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
) AS p
參考: 小提琴
我至少能想到幾個想法。
第一個想法:
SELECT symbol,
SUBSTRING_INDEX(prices,',',1)-SUBSTRING_INDEX(prices,',',-1) AS price_change
FROM
(SELECT symbol, GROUP_CONCAT(price ORDER BY `date` DESC) prices
FROM ticks
WHERE `date` >= '2021-02-19' AND `date` <= '2021-02-21'
GROUP BY symbol) a;
第二個想法:
SELECT a.symbol,
SUM(CASE WHEN a.`date`=max_date THEN price END) AS u,
SUM(CASE WHEN a.`date`=min_date THEN price END) AS m,
SUM(CASE WHEN a.`date`=max_date THEN price END)-SUM(CASE WHEN a.`date`=min_date THEN price END) AS price_change
FROM ticks a
JOIN
(SELECT symbol, MIN(`date`) AS min_date, MAX(`date`) AS max_date
FROM ticks WHERE `date` >= '2021-02-19' AND `date` <= '2021-02-21'
GROUP BY symbol) b
ON a.symbol=b.symbol
GROUP BY a.symbol;
小提琴演示: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=0168329820ddbacfa5d0356a6f3ba2ea
我們可以使用臨時表來計算結果。 所有現代 MySQL 服務器版本都支持臨時表。 它們僅在當前連接期間持續。 有關詳細信息,請參閱臨時表的描述。
請參閱以下 SQL:
CREATE TEMPORARY TABLE min_date_tbl (
`symbol` varchar(4),
`min_date` datetime
);
CREATE TEMPORARY TABLE max_date_tbl (
`symbol` varchar(4),
`max_date` datetime
);
CREATE TEMPORARY TABLE min_price_tbl (
`symbol` varchar(4),
`min_price` int
);
CREATE TEMPORARY TABLE max_price_tbl (
`symbol` varchar(4),
`max_price` int
);
INSERT INTO min_date_tbl (SELECT symbol, MIN(date) as min_date from ticks where date >= '2021-02-19' and date <= '2021-02-21' group by symbol);
INSERT INTO max_date_tbl (SELECT symbol, MAX(date) as max_date from ticks where date >= '2021-02-19' and date <= '2021-02-21' group by symbol);
INSERT INTO min_price_tbl (SELECT t1.symbol, t1.price as min_price FROM ticks t1, min_date_tbl t2 WHERE t1.symbol=t2.symbol AND t1.date=t2.min_date);
INSERT INTO max_price_tbl (SELECT t1.symbol, t1.price as max_price FROM ticks t1, max_date_tbl t2 WHERE t1.symbol=t2.symbol AND t1.date=t2.max_date);
SELECT t1.symbol as SYMBOL, (t2.max_price - t1.min_price) as PRICE_CHANGE FROM min_price_tbl t1, max_price_tbl t2 WHERE t1.symbol=t2.symbol
我在dbfiddle 上創建並測試了這個 SQL 代碼。 它產生了所需的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.