2014-04-05 214 views
2

編輯:SQL複雜的查詢

我的表包含的ID,segmentID,月,年和平均速度, 我已經創建sqlfiddle與這裏的一些演示數據:http://sqlfiddle.com/#!2/183c1/1

我需要確定段,其中平均駕駛速度比上個月下降了10%以上。

有人可以幫我嗎? 感謝

感謝

+0

什麼RDBMS您使用的? – Mureinik

+0

您是否可以使用示例數據來更新問題? – jpw

+0

@Mureinik - mysql –

回答

1

這裏是我的解決方案

Sqlfidle demo

的關鍵是要保持前一個月和未來之間的軌道,i` m年份* 100 +月份和年份之後,並在年份* 100 +月份字段中檢查差異1和89。 另外,MySQL不支持CTE並且使用派生表使查詢變醜。

代碼:

select s.month,s.speed,m.month as prevmonth,m.speed as sp, 100-s.speed/m.speed*100 as speeddiff from 
(SELECT segmentid,month,year*100+month as mark,avg(avgSpeed) as speed from travels 
group by segmentid,month,year*100+month 
) as s 
, 
(SELECT segmentid,month,year*100+month as mark,avg(avgSpeed) as speed from travels 
group by segmentid,month,year*100+month 
) as m 
where s.segmentid=m.segmentid and (s.mark=m.mark+1 or s.mark=m.mark+89) and (m.speed-(m.speed/10))>s.speed; 

CTE代碼上的每個數據庫的工作,除了MySQL的

with t as(SELECT segmentid,month,year*100+month as mark,avg(avgSpeed) as speed from travels 
group by segmentid,month,year*100+month 
) 
select s.month,s.speed,m.month as prevmonth,m.speed as sp, 100-s.speed/m.speed*100 as speeddiff from t s 
inner join t m on s.segmentid=m.segmentid and (s.mark=m.mark+1 or s.mark=m.mark+89) 
where (m.speed-(m.speed/10))>s.speed; 
0

這需要一個自聯接。這個答案會讓你開始。你可以處理細節。

select somefields 
from yourtable t1 join yourtable t2 on t1.something = t2.something 
where t1.month = whatever 
and t2.month = t1.month + 1 
and t2.speed <= t1.speed * .9 
1

您需要選擇每個月,加入下個月(這是由於您的表結構有點複雜),並找到減少(/增加)。試試下面的複雜查詢

SELECT 
    t1.segmentID, t1.month, t1.year, AVG(t1.avgSpeed) as avgSpeed1, 
    AVG(t2.avgSpeed) as avgSpeed2, 
    1-(AVG(t1.avgSpeed)/AVG(t2.avgSpeed)) as decrease 
FROM 
    travels t1 
LEFT JOIN 
    travels t2 
ON 
    CONCAT(t2.year,'-',LPAD(t2.month,2,'00'),'-',LPAD(1,2,'00')) = DATE_ADD(CONCAT(t1.year,'-',LPAD(t1.month,2,'00'),'-',LPAD(1,2,'00')), INTERVAL -1 MONTH) 
GROUP BY 
    segmentID, month, year 
HAVING 
    avgSpeed1/avgSpeed2 < .9 

這裏是更新SQLFiddle - http://sqlfiddle.com/#!2/183c1/25

+0

內部聯接就足夠了。 –