2012-08-10 44 views
2

假設我有兩個表,「用戶」和「審計」,並且每次用戶狀態更改時都會通過觸發器填充審計表。我試圖從這兩個表中進行選擇,並獲取用戶條目(唯一)以及相關的最新審計條目。說表有以下字段:加入2個表(一對多)並在第二個表中獲取最新條目

用戶:

  • ID
  • 用戶名
  • 電子郵件
  • 狀態

審計:

  • 號(只是一個任意自動增量)
  • USER_ID(FK)
  • NEW_STATUS
  • created_at(日期/時間發生這種情況)

因此,對於每個用戶條目,有多個審計條目。

所以,最終我需要的結果被說(其中斜體部分從審計結果,以及非斜體是在mysql結果集行的用戶部分):
,約翰,[email protected],10,5,,10,2012-08-10-10:15:59

現在,我可以看到的唯一的辦法是做複合選擇,在那裏我做這樣的事情: SELECT U. *,(SELECT * FROM audit A2 where A2.id = max(A.id))FROM users U lef t加入審計A(U.id = A.user_id);

問題是,如果你有成千上萬或者成千上萬的用戶結果,你會在DB內部進行n + 1個查詢 - 這實際上效率很低。

有關如何在不使用複合SELECTS的情況下將其作爲一個SQL語句編寫的任何想法?

回答

5

我假設總是有相應的審覈條目,並因此使用INNER JOIN。同樣假設同一用戶沒有兩個具有相同created_at日期的審覈條目。

select u.id, u.username, u.email, u.status, 
    a.id, a.new_status, a.created_at 
from users u 
inner join (
    select user_id, max(created_at) as MaxCreated 
    from audit 
    group by user_id 
) am on u.id = am.user_id 
inner join audit a on am.user_id = a.user_id and am.MaxCreated = a.created_at 
+0

謝謝,但不會導致1000 + 1的內部SELECT語句,如果有例如1000個用戶?它會爲所有用戶做第一次選擇,然後爲每個用戶選擇一個結果。我試圖實現的是一個避免這種情況的選擇聲明。 (當然,如果有可能的話,呵呵) – Sarel 2012-08-10 17:02:15

+0

@Sarel不,內部選擇是一個派生表,即它將運行一次。請注意,它不是相關的子查詢 - 您可以自行運行子查詢,它不使用其他表中的數據。那個派生表然後被加入到'users'和'audit'中。 – RedFilter 2012-08-10 18:00:27

+0

啊哇,真棒!謝謝你......這就像我們生產服務器上的魅力:) *高五* – Sarel 2012-08-10 19:13:34

相關問題