2017-08-15 49 views
3

我通過SQL連接2個表並添加where子句。連接由where子句中的條件完成。 我想知道是否有所區別where子句期望的連接子句是由括號分組。在SQL中,條件是否在連接的情況下分組?

要求示例:是等效於示例2和示例3的示例1?

實施例1(沒有分組):

SELECT * FROM employees, vacation 
WHERE employees.first_name = 'Maria' and vacation_start > 2017 
    AND employees.employee_id = vacation.employee_id 

實施例2(除了連接子句一切被分組):

SELECT * FROM employees, vacation 
WHERE (employees.first_name = 'Maria' and vacation_start > 2017) 
    AND employees.employee_id = vacation.employee_id 

實施例3(加入子句是第一其中參數):

SELECT * FROM employees, vacation 
WHERE employees.employee_id = vacation.employee_id 
    AND (employees.first_name = 'Maria' and vacation_start > 2017) 

我一直認爲數據庫會優化這種查詢。 但他們呢?我主要與MariaDB和SQLite合作。

回答

2

是的,它們是等價的。但是,你應該使用明確的加入,而不是老WHERE語法:

SELECT * 
FROM employees 
JOIN vacation 
    ON employees.employee_id = vacation.employee_id 
WHERE employees.first_name = 'Maria' and vacation_start > 2017; 

簡單的邏輯:

-- AND has associative property 
cond1 AND cond2 AND cond3 
<=> 
(cond1 AND cond2) AND cond3 
<=> 
cond1 AND (cond2 AND cond3) 
+0

我確實更喜歡顯式連接,因爲它使表關係清晰。然而,查詢是編程庫的一個結果,我無法強制從加入選擇變體( – capfan

+1

@capfan,'JOIN'語法不是變體 - 它是自1992年以來的標準語法。任何編程都沒有任何藉口庫不支持它。 –

1
  1. 的WHERE條件都不會有問題的順序,但是你寫的表的順序連接中不物。
  2. 如果您保留加入左側的記錄較少的表會提供更好的性能。
  3. 關於您的WHERE條件,Optimizer將始終將謂詞向下推,以加快聯接操作。這意味着它將首先在表格上應用條件(employees.first_name ='Maria'和vacation_start> 2017),然後在過濾的記錄集上執行join(employees.employee_id = vacation.employee_id)。

    如果您查看您的查詢的解釋計劃,您將更瞭解它。

1

分組,其中子句僅首先重要的針對你的情況的邏輯表達式。例如;

(A和B和C)

A和(B和C)

是等價的。

但是

(A或B和C)

(A或B)和C

是不同的。

在你的例子中,所有查詢都是相同。如果您的數據量非常大,則您的分組選擇可能會出現一些性能問題。如果不是沒有問題。

相關問題