2017-04-05 59 views
0

兩個表 - all_dataselected_place_day_hours比較內使用加入,其中

all_dataplace_iddayhourmetric

selected_place_day_hours有場place_iddayhour

我需要子集all_data,使得只有具有place_id,的記錄,hourselected_place_day_hours被選中。

我可以去它

1.使用inner join

select a.* 
from all_data as a 
inner join selected_place_day_hours as b 
on (a.place_id = b.place_id) 
and (a.day = b.day) 
and (a.hour = b.hour) 
; 

2.使用where in

select * 
from all_data 
where 
    place_id in (select place_id from selected_place_day_hours) 
    and day in (select day from selected_place_day_hours) 
    and hour in (select day from selected_place_day_hours) 
; 

我想對爲什麼一些想法兩種方式,什麼時候,如果你會從功能和perfo中選擇一個愛情觀點?

一個想法是,在#2以上,可能子選擇不是性能友好的,也更長的代碼。

回答

1

這兩者在語義上是不同的。

IN做了半聯接,這意味着它返回一個從all_data無論多少行selected_place_day_hours匹配。

JOIN可以返回多行。

因此,第一條建議是使用適合您想要完成的版本。

假設select_place_day_hours中的數據最多隻能保證一次匹配,那麼您在性能方面存在問題。第一條建議是對數據和系統上的兩個查詢進行嘗試。然而,JOIN經常被優化,至少和IN一樣,所以這通常是一個安全的選擇。

1

現在,SQL傾向於忽略你所說的並且做它自己的事情。

這就是爲什麼SQL是聲明語言,而不是一個編程語言:你告訴它你想要什麼,而不是如何去做。 SQL解釋器可以計算出你想要的結果,並制定自己的計劃來獲得結果。

在這種情況下,無論您如何編寫它,2個版本都可能會生成相同的計劃。無論如何,所選擇的計劃將是最有效的計劃。

的理由比舊where語法喜歡join語法是:

  • 爽一下:你不想讓任何人與代碼是老式的捕你
  • join語法容易適應外部聯接
  • join語法允許你來分隔通過區分連接來自另外的過濾器部分join之間where

原因做不是包括是否更好,因爲解釋器會處理。

0

這些是更多的註釋,太長的評論。

首先應該顯示你的兩個查詢是不同的。 (也許你寫的第二個查詢是錯誤的查詢)

例如:

all_data

place_id day  hour other_cols... 
1   4  3  .... 

selected_place_day_hours

place_id day  hour 
1   4  9 
4444  4444 6 

然後你查詢將得到沒有行回報,你的第二將返回(1, 4, 6)

還要說明一點的是,如果(place_id, day, hour)是獨一無二的,你的第一個查詢在下面的查詢

SELECT * 
FROM all_data 
WHERE 
    (place_id, day, hour) IN (
     SELECT place_id, day, hour 
     FROM selected_place_day_hours 
    ); 
+0

@的同樣的目的會不'和'照顧這個? – user3206440

+0

@ user3206440否如上例所示:'place_id IN(1,4444)AND day IN(4,444)AND hour IN(9,6)'不等於'(place_id,day,hour)IN( 1,4,9),(4444,4444,6)) –