![](/img/trans.png)
[英]How to get highest occuring value from table using another column as a multiplier instead of row count MySQL
[英]How to get the value using another column and get difference between each row in MySQL or SQL?
finish_position official_rating date Difference
11 NULL 2013-09-18 0.00
4 NULL 2013-11-08 0.00
3 NULL 2014-02-27 0.00
6 65 2014-04-24 0.00
13 63 2014-05-05 0.00
1 59 2014-07-04 0.00
2 65 2014-08-04 (59-65)= -6.00
12 68 2014-10-28 (59-68)= -9.00
9 62 2014-12-09 (59-62)= -3.00
5 65 2015-01-08 (59-65)= -6.00
7 60 2015-01-29 (59-60)= -1.00
11 65 2015-04-08 (59-65)= -6.00
5 63 2015-04-22 (59-63)= -4.00
1 60 2015-07-14 0.00
9 60 2015-08-04 (60-60)= 0.00
8 56 2016-01-22 (60-56)= 4.00
4 52 2016-02-26 (60-52)= 8.00
7 50 2016-03-31 (60-50)= 10.00
8 48 2016-04-25 (60-48)= 12.00
4 56 2016-07-12 (60-56)= 4.00
8 47 2016-09-23 (60-47)= 13.00
9 52 2017-06-20 (60-52)= 8.00
1 50 2017-07-04 0.00
3 55 2017-07-20 (50-55)= -5.00
3 48 2017-07-29 (50-48)= 2.00
我有以上兩列(finish_position,official_rating)。 我想獲得差異列的上述值。 每當finish_position 為1 時,差異為0。以上所有行的差異為0,直到這一行(從上到下的第一行finish_position 等於1)您可以從上表中得到想法。 我需要得到每行之間的差異finish_positions之間的official_rating等於1。我希望你們理解這個問題,請幫助我做到這一點。
我想要 SQL 代碼。
編輯:
以下是產生預期輸出的臨時解決方案。 我編輯是因為有一些條件我沒有包括在內。
您可以復制代碼並將其粘貼到此處並運行: https : //rextester.com/l/postgresql_online_compiler
WITH LOG AS
(
SELECT 11 AS FINISH_POSITION
, NULL AS OFFICIAL_RATING
, '2013-09-18' :: DATE AS RATING_DATE
UNION ALL
SELECT 4 AS FINISH_POSITION
, NULL AS OFFICIAL_RATING
, '2013-11-08' :: DATE AS RATING_DATE
UNION ALL
SELECT 3 AS FINISH_POSITION
, NULL AS OFFICIAL_RATING
, '2014-02-27' :: DATE AS RATING_DATE
UNION ALL
SELECT 6 AS FINISH_POSITION
, '65' AS OFFICIAL_RATING
, '2014-04-24' :: DATE AS RATING_DATE
UNION ALL
SELECT 13 AS FINISH_POSITION
, '63' AS OFFICIAL_RATING
, '2014-05-05' :: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '59' AS OFFICIAL_RATING
, '2014-07-03' :: DATE AS RATING_DATE
UNION ALL
SELECT 2 AS FINISH_POSITION
, '65' AS OFFICIAL_RATING
, '2014-08-04' :: DATE AS RATING_DATE
UNION ALL
SELECT 12 AS FINISH_POSITION
, '68' AS OFFICIAL_RATING
, '2014-10-28' :: DATE AS RATING_DATE
UNION ALL
SELECT 9 AS FINISH_POSITION
, '62' AS OFFICIAL_RATING
, '2014-12-09' :: DATE AS RATING_DATE
UNION ALL
SELECT 5 AS FINISH_POSITION
, '65' AS OFFICIAL_RATING
, '2015-01-08' :: DATE AS RATING_DATE
UNION ALL
SELECT 7 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2015-01-29' :: DATE AS RATING_DATE
UNION ALL
SELECT 11 AS FINISH_POSITION
, '65' AS OFFICIAL_RATING
, '2015-04-08' :: DATE AS RATING_DATE
UNION ALL
SELECT 5 AS FINISH_POSITION
, '63' AS OFFICIAL_RATING
, '2015-04-22' :: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2015-07-14' :: DATE AS RATING_DATE
UNION ALL
SELECT 9 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2015-08-04' :: DATE AS RATING_DATE
UNION ALL
SELECT 8 AS FINISH_POSITION
, '65' AS OFFICIAL_RATING
, '2016-01-22' :: DATE AS RATING_DATE
UNION ALL
SELECT 4 AS FINISH_POSITION
, '52' AS OFFICIAL_RATING
, '2016-02-26' :: DATE AS RATING_DATE
UNION ALL
SELECT 7 AS FINISH_POSITION
, '50' AS OFFICIAL_RATING
, '2016-03-31' :: DATE AS RATING_DATE
UNION ALL
SELECT 8 AS FINISH_POSITION
, '48' AS OFFICIAL_RATING
, '2016-04-25' :: DATE AS RATING_DATE
UNION ALL
SELECT 4 AS FINISH_POSITION
, '56' AS OFFICIAL_RATING
, '2016-07-12' :: DATE AS RATING_DATE
UNION ALL
SELECT 8 AS FINISH_POSITION
, '47' AS OFFICIAL_RATING
, '2016-09-23 ' :: DATE AS RATING_DATE
UNION ALL
SELECT 9 AS FINISH_POSITION
, '52' AS OFFICIAL_RATING
, '2017-06-20' :: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '50' AS OFFICIAL_RATING
, '2017-07-04' :: DATE AS RATING_DATE
UNION ALL
SELECT 3 AS FINISH_POSITION
, '55' AS OFFICIAL_RATING
, '2017-07-20' :: DATE AS RATING_DATE
UNION ALL
SELECT 3 AS FINISH_POSITION
, '48' AS OFFICIAL_RATING
, '2017-07-29' :: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '58' AS OFFICIAL_RATING
, '2017-08-15' :: DATE AS RATING_DATE
UNION ALL
SELECT 2 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2017-08-20' :: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '48' AS OFFICIAL_RATING
, '2017-08-22 ' :: DATE AS RATING_DATE
UNION ALL
SELECT 9 AS FINISH_POSITION
, '52' AS OFFICIAL_RATING
, '2017-08-27' :: DATE AS RATING_DATE
UNION ALL
SELECT 2 AS FINISH_POSITION
, NULL AS OFFICIAL_RATING
, '2017-09-05':: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '48' AS OFFICIAL_RATING
, '2017-09-17':: DATE AS RATING_DATE
UNION ALL
SELECT 1 AS FINISH_POSITION
, '51' AS OFFICIAL_RATING
, '2017-09-21':: DATE AS RATING_DATE
UNION ALL
SELECT 11 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2017-09-25':: DATE AS RATING_DATE
UNION ALL
SELECT 13 AS FINISH_POSITION
, '63' AS OFFICIAL_RATING
, '2017-09-30':: DATE AS RATING_DATE
UNION ALL
SELECT 14 AS FINISH_POSITION
, '61' AS OFFICIAL_RATING
, '2017-10-04':: DATE AS RATING_DATE
UNION ALL
SELECT 7 AS FINISH_POSITION
, '49' AS OFFICIAL_RATING
, '2017-10-05':: DATE AS RATING_DATE
UNION ALL
SELECT 9 AS FINISH_POSITION
, NULL AS OFFICIAL_RATING
, '2017-10-09':: DATE AS RATING_DATE
UNION ALL
SELECT 11 AS FINISH_POSITION
, '60' AS OFFICIAL_RATING
, '2017-10-15':: DATE AS RATING_DATE
)
SELECT T3.FINISH_POSITION AS FINISH_POSITION
, T3.OFFICIAL_RATING AS OFFICIAL_RATING
, T3.DATE AS DATE
, CASE WHEN T3.RATING_OF_1 IS NULL OR T3.OFFICIAL_RATING IS NULL THEN 0
ELSE CAST(T3.RATING_OF_1 AS INT) - CAST(T3.OFFICIAL_RATING AS INT)
END AS DIFFERENCE
FROM
(
SELECT L.FINISH_POSITION AS FINISH_POSITION
, L.OFFICIAL_RATING AS OFFICIAL_RATING
, L.RATING_DATE AS DATE
, L.OFFICIAL_RATING AS RATING_OF_1
FROM LOG AS L
WHERE L.RATING_DATE < (SELECT MIN(RATING_DATE)
FROM LOG
WHERE FINISH_POSITION = 1)
UNION
SELECT L.FINISH_POSITION AS FINISH_POSITION
, L.OFFICIAL_RATING AS OFFICIAL_RATING
, L.RATING_DATE AS DATE
, L.OFFICIAL_RATING AS RATING_OF_1
FROM LOG AS L
WHERE OFFICIAL_RATING IS NULL
UNION
SELECT L.FINISH_POSITION AS FINISH_POSITION
, L.OFFICIAL_RATING AS OFFICIAL_RATING
, L.RATING_DATE AS DATE
, T2.RATING_OF_1 AS RATING_OF_1
FROM LOG AS L
LEFT JOIN
(
SELECT T1.OFFICIAL_RATING_OF_1 AS RATING_OF_1
, T1.DATE AS DATE
, LEAD(T1.DATE) OVER (ORDER BY T1.DATE ASC) AS NEXT_RATEING_OF_1
FROM (
SELECT FINISH_POSITION
, OFFICIAL_RATING AS OFFICIAL_RATING_OF_1
, RATING_DATE AS DATE
FROM LOG
WHERE FINISH_POSITION = 1
) AS T1
WHERE T1.OFFICIAL_RATING_OF_1 IS NOT NULL
) AS T2
ON L.RATING_DATE > T2.DATE AND L.RATING_DATE < T2.NEXT_RATEING_OF_1
WHERE OFFICIAL_RATING IS NOT NULL AND T2.NEXT_RATEING_OF_1 IS NOT NULL
UNION
SELECT FINISH_POSITION AS FINISH_POSITION
, OFFICIAL_RATING AS OFFICIAL_RATING
, RATING_DATE AS DATE
, OFFICIAL_RATING AS OFFICIAL_RATING_OF_1
FROM LOG
WHERE FINISH_POSITION = 1
) AS T3
UNION
SELECT L.FINISH_POSITION AS FINISH_POSITION
, L.OFFICIAL_RATING AS OFFICIAL_RATING
, L.RATING_DATE AS DATE
, CASE WHEN OFFICIAL_RATING IS NULL THEN 0
ELSE CAST(T3.RATING_OF_1 AS INT) - CAST(L.OFFICIAL_RATING AS INT)
END AS DIFFERENCE
FROM LOG AS L
RIGHT OUTER JOIN
(
SELECT DISTINCT
T2.RATING_OF_1
, T2.DATE AS DATE
, T2.NEXT_RATEING_OF_1
FROM
(
SELECT T1.OFFICIAL_RATING_OF_1 AS RATING_OF_1
, T1.DATE AS DATE
, LEAD(T1.DATE) OVER (ORDER BY T1.DATE ASC) AS NEXT_RATEING_OF_1
FROM (
SELECT FINISH_POSITION
, OFFICIAL_RATING AS OFFICIAL_RATING_OF_1
, RATING_DATE AS DATE
FROM LOG
WHERE FINISH_POSITION = 1
) AS T1
) AS T2
WHERE T2.NEXT_RATEING_OF_1 IS NULL
) AS T3
ON L.RATING_DATE > T3.DATE
ORDER BY DATE ASC
;
輸出:
請注意,您必須刪除WITH
子句並更改表和列名稱才能針對您的表運行。 例如,我創建的表名為 LOG。 此外,代碼是基於 PostgreSQL 的,因此與其他版本的 SQL 相比,存在語法限制。
您沒有提及您使用的是哪個版本的 MySQL。 在 MySQL 8.x 中,您可以使用LAG()
函數。 例如:
select
*,
official_rating - lag(official_rating) over(order by date) as difference
from t
order by date
請參閱12.21.1 窗口功能說明。
我曾想象過這樣做,我會盡力解釋。
請注意,我的日期列名為 datec,表名為 test
首先,我選擇了結果的第一部分,我不會計算任何差異(直到第一個數字 1 出現)。 我用這個查詢做到了:
select finish_position, official_rating, datec, 0.00 as difference from test where datec <= (select min(datec) from test where finish_position = 1
然后我選擇了表的第二部分,我將在其中計算差異並將其標記為空,因為我將計算外部查詢中的差異。 使用此查詢選擇第二部分:
select finish_position, official_rating, datec, null as difference from test where datec > (select min(datec) from test where finish_position = 1)
最后我將這兩個結果結合起來並寫了一個查詢:
select finish_position,official_rating, datec , case when difference = 0.00 then difference else official_rating - lag(official_rating) over(order by datec) end difference_1 from ( select finish_position, official_rating, datec, 0.00 as difference from test where datec <= (select min(datec) from test where finish_position = 1) union select finish_position, official_rating, datec, null as difference from test where datec > (select min(datec) from test where finish_position = 1)) t1 order by datec;
最后我為你創建了一個小演示(我沒有輸入完整的數據但是......)。 看一看...
經過與 OP 的更多討論,我終於完成了這段代碼:
select finish_position,official_rating, datec
, case when finish_position = 1 then 0.00
when t1.datec >= (select tt.datec
from test tt
where DATEDIFF(tt.datec, t1.datec) in
(select max(datediff(ttt.datec, t1.datec))
from test ttt
where finish_position = 1
and ttt.datec <= t1.datec))
then (select t.official_rating
from test t
where datediff(t.datec, t1.datec) in
(select max(datediff(ttt.datec, t1.datec))
from test ttt
where finish_position = 1
and ttt.datec <= t1.datec)) - t1.official_rating
end difference
from (
select finish_position, official_rating, datec
, case when finish_position = 1 then null
else 0.00
end as difference
from test
where datec <= (select min(datec)
from test
where finish_position = 1)
union
select finish_position, official_rating, datec, null as difference
from test
where datec > (select min(datec)
from test
where finish_position = 1)) t1
order by datec;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.