2017-07-22 71 views
0

我有這個表:的MS Access獲得平均時間

button_log 
    ======================================= 
    |ID | table_no | transaction_datetime | 
    ======================================= 
    | 1 | 1  | 22/07/2017   | 
    | 2 | 1  | 22/07/2017   | 
    | 3 | 1  | 22/07/2017   | 
    | 4 | 1  | 22/07/2017   | 

service_time 
    =============================== 
    |ID | table_no | service_time | 
    =============================== 
    | 1 | 1  | 00:00:06 | 
    | 2 | 1  | 00:00:05 | 
    | 3 | 1  | 00:00:03 | 
    | 4 | 1  | 00:00:10 | 

我有這個疑問:

select b.table_no, count(*) as total_call_count, sum(TimeValue(c.service_time) * 86400) as total_time from button_log b, service_time_log c where b.table_no = c.table_no and Format(b.transaction_datetime,""DD/MM/yyyy"") = '" & Date.Now.ToString("d") & "' group by b.table_no 

,但我有這個結果

========================================== 
    |table_no | total_call_count | total_time| 
    ========================================== 
    | 1  |  4   | 96  | 

我期望的結果是:

========================================== 
    |table_no | total_call_count | total_time| 
    ========================================== 
    | 1  |  4   | 24  | 

我怎樣才能total_time總和每記錄一次?

+0

你不想總和total_time,你希望該值只顯示一次?不要使用Sum,只要檢索total_time字段並將其包含在GROUP BY子句中。 – June7

+0

@ June7但後來我會有4行作爲結果..我只需要1個結果。 –

+0

好的,您是否更改了示例數據?我認爲他們都有相同的服務時間,我想知道它是否真正具有代表性。 – June7

回答

1

我假定表名在定義中是錯誤的。您編寫了service_time,但在查詢中使用了service_time_log。我會用第二個。結果乘以4,因爲button_log中有4行與where子句中的條件匹配。所以你需要先清除button_log表。

select b.table_no, count(*) as total_call_count, sum(TimeValue(c.service_time) * 86400) as total_time 
from (select distinct table_no, transaction_datetime from button_log) b, service_time_log c 
where b.table_no = c.table_no and Format(b.transaction_datetime,""DD/MM/yyyy"") = '" & Date.Now.ToString("d") & "' 
group by b.table_no 

使用替代解決方案加入:

select b.table_no, count(*) as total_call_count, sum(TimeValue(c.service_time) * 86400) as total_time 
from 
    (select distinct table_no, transaction_datetime from button_log 
    where Format(transaction_datetime,""DD/MM/yyyy"") = '" & Date.Now.ToString("d") & "') b 
    inner join service_time_log c on b.table_no = c.table_no 
group by b.table_no 
+0

爲了澄清某些使用正確的查詢術語,原始查詢使用了_cross join_(逗號分隔的沒有任何連接關鍵字的表列表),該列表從每個表中取出_every combination_行。在這種情況下,4個button_log行* 4個service_time行,因此它將相同的值相加4次。 –

+0

實際上,可以在不使用「join」關鍵字的情況下正確執行連接,因爲連接條件在where子句中提供。看到那裏'b.table_no = c.table_no'。 – Han

+0

我只是指出這被稱爲交叉連接,儘管WHERE條件會過濾掉額外的行,但默認行爲仍然是產生錶行的完整笛卡爾乘積......每行的組合。像SQL Server,Oracle等先進的執行計劃優化的高級數據庫管理系統可以使這個問題變得微不足道,但在我使用Access進行測試時,它不一定非常聰明。它將在基於WHERE過濾記錄之前執行完全交叉連接。顯式指定連接類型(INNER JOIN在此處工作)可以更有效。 –

0

不要日期/時間處理複雜,所以試試這個:

"Select 
    button_log.table_no, 
    Count(*) As total_call_count, 
    (Select Sum(service_time_log.service_time) * 86400 
    From service_time_log 
    Where service_time_log.table_no = button_log.table_no) As total_time 
From 
    button_log 
Where 
    button_log.transaction_datetime = #" & DateTime.Today.ToString("yyyy'/'MM'/'dd") & "# 
Group By 
    button_log.table_no" 
+0

你說不要讓日期/時間處理複雜化,但爲什麼複雜的字符串轉換爲今天的日期?爲什麼不直接在SQL語句中調用Date()函數,如'button_log.transaction_datetime = Date()'? –

+0

你可能是對的,但我不確定這是否會在未知的環境中工作。 – Gustav

0

SELECT button_log.table_no, Count(transaction_datetime) AS CountOfTransDate, Q1.TotalTime FROM (SELECT table_no, Sum(TimeValue([service_time])*86400) AS TotalTime FROM service_time_log GROUP BY table_no) AS Q1 INNER JOIN button_log ON Q1.table_no = button_log.table_no WHERE button_log.transaction_datetime=Date() GROUP BY button_log.table_no, Q1.TotalTime;

你的例子顯示了國際日期格式。由於我的數據庫使用Access標準(美國)格式,我不必操縱日期。根據需要調整您的情況。

但是,由於service_time_log沒有日期值,因此它的記錄不能按日期過濾,因此TotalTime與button_log日期有什麼關係?每個table_no是否只有一個日期?

你的例子顯示了table_no 1在每個表中的4條記錄。每個table_no在每個表中總會有相同數量的記錄嗎?