2016-11-18 38 views
0

我有一個相當簡單的查詢,該大型數據集進行操作。差異DATEADD

當我使用IN操作符,我得到某種結果,我相信這是正確的。
當我使用DATE_ADD()時,我得到一個我認爲不正確的結果。

該查詢是如下:(2條註釋線是2個選項)

SELECT 
    e.date, er.ratio, e.total as recalc 
FROM 
    equity e 
     JOIN 
    exchange_rate er ON e.date = er.date 
     AND LOWER(er.currency) = LOWER(e.currency) 
    join account a 
     on e.account = a.id 
WHERE 
    -- e.date >= DATE_ADD(DATE(NOW()), INTERVAL - 5 DAY) 
    -- e.date in ('2016-11-14','2016-11-15','2016-11-16') 
    and a.lynx_country = 'BE' 

IN後括號內的值是返回的值時,我會做

SELECT 
    distinct date 
FROM 
    equity e 
WHERE 
    e.date >= DATE_ADD(DATE(NOW()), INTERVAL - 5 DAY) 

此外,結果集是針對2個查詢一樣,但是當我添加一個包裝查詢,我得到一個顯著差異

完整的查詢,包括包裝:

select ROUND(SUM(total)/ratio, 2) as agg, date 
from (
SELECT 
    e.date, er.ratio, e.total 
FROM 
    equity e 
     JOIN 
    exchange_rate er ON e.date = er.date 
     AND LOWER(er.currency) = LOWER(e.currency) 
    join account a 
     on e.account = a.id 
WHERE 
    e.date >= DATE_ADD(DATE(NOW()), INTERVAL - 5 DAY) 
    -- e.date in ('2016-11-14','2016-11-15','2016-11-16') 
    and a.lynx_country = 'BE' 
    ) dummy 
    group by date 

錯誤結果:DATE_ADD(DATE(NOW()),INTERVAL - 第5天)

agg   | date 
------------------------ 
68833599.13 | 2016-11-14 
69350727.47 | 2016-11-15 
69351461.28 | 2016-11-16 

正確的結果:在( '2016年11月14日',「2016年11月15日」, '2016年11月16日')

agg   | date 
------------------------- 
101956327.03 | 2016-11-14 
102722297.52 | 2016-11-15 
102723384.45 | 2016-11-16 

所有幫助讚賞

+0

請通過展示什麼是真正被兩個查詢之間變化澄清你的問題。 'WHERE'子句正在改變,但在第二個查詢中,您正在進行聚合。 –

+0

第一個查詢的輸出(沒有聚合包裝)對於兩個變體是否相同?輸出是什麼? – Kleskowy

+0

是的,輸出是9000行 – ShadowFlame

回答

0

請你嘗試這些?

SELECT 
    'query a' 
, sum(case when e.date >= '2016-11-14' and < '2016-11-15' then total end) day1 
, sum(case when e.date >= '2016-11-15' and < '2016-11-16' then total end) day2 
, sum(case when e.date >= '2016-11-16' and < '2016-11-17' then total end) day3 
FROM equity e 
JOIN exchange_rate er ON e.date = er.date AND LOWER(er.currency) = LOWER(e.currency) 
JOIN account a ON e.account = a.id 
WHERE e.date >= DATE_ADD(DATE(NOW()), INTERVAL - 5 DAY) 
    and a.lynx_country = 'BE' 
; 

SELECT 
    'query b' 
, sum(case when e.date >= '2016-11-14' and < '2016-11-15' then total end) day1 
, sum(case when e.date >= '2016-11-15' and < '2016-11-16' then total end) day2 
, sum(case when e.date >= '2016-11-16' and < '2016-11-17' then total end) day3 
FROM equity e 
JOIN exchange_rate er ON e.date = er.date AND LOWER(er.currency) = LOWER(e.currency) 
JOIN account a ON e.account = a.id 
WHERE e.date in ('2016-11-14','2016-11-15','2016-11-16') 
    and a.lynx_country = 'BE' 
; 

然後嘗試:

SELECT 
    date(e.`date`) as e_date, SUM(e.total) 
FROM equity e 
JOIN exchange_rate er ON e.date = er.date AND LOWER(er.currency) = LOWER(e.currency) 
JOIN account a ON e.account = a.id 
WHERE e.date >= DATE_ADD(DATE(NOW()), INTERVAL - 5 DAY) 
    and a.lynx_country = 'BE' 
GROUP BY 
    date(e.`date`) 

我認爲問題是,數據包含的信息分佈在那些天的時間範圍,並試圖使用(...)過於具體的方法選擇數據。

另外。在日期/時間範圍內非常小心「之間」。在前面的2個查詢中少於這個問題的介入確保3個範圍之間絕對沒有重疊。如果您使用任何其他方法,則可能會導致數據中的重疊或空白。 http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx

+0

,只有很小的變化(...和e.date <...每行),這兩種情況下都會得到相同的結果。 但是,這在生產環境中不會有用,因爲我不打算自己計算所有這些日期。 MySql應該這樣做.. – ShadowFlame

+0

沒有@ShadowFlame說e.date是'DATE'而不是'DATETIME'嗎?如果這是正確的,那麼很難看出這與原來的「不工作」版本在邏輯上有何不同。我認爲我忽略了一些東西,但不清楚可能是什麼。 –

+0

@ Michael-sqlbot,是的,我確實這麼說。 – ShadowFlame