2013-11-22 97 views
0

我陷入了一個問題。我有3桌,我加入他們,但不能得到正確的答案,如果任何人都可以幫助我,我將不勝感激。所以我想要的是,Answer給我看看未使用的材質。表:enter image description hereMySQL左加入(我認爲)

有了很多的幫助,我得到了所有與此有關未使用的材料:

SELECT DISTINCT(Materials.Material_Name) AS Unused_materials FROM Materials 
LEFT JOIN Table2 ON Table2.Material_Number = Materials.Material_Number 
LEFT JOIN Table1 ON Table1.Procedure_Name = Table2.Procedure_Name 
WHERE Table1.Procedure_Name IS NULL 

更新: 如果我可以要求在同一職位一個問題。也許任何人都會知道如何獲得上述信息,只需要通緝日。喜歡:2012-11-20未使用的材料?

+2

選擇null選擇null – Hogan

回答

0

約翰以上幾乎都有它的(未使用的材料仍然存在TABLE_2,因爲表2只是一種Material_Number(這如果是1過程名的查找:1的關係似乎是一個愚蠢的加法)還是需要加入對錶1得到空值

所以

SELECT * 
    FROM Materials c 
     LEFT JOIN Table2 b ON b.Material_Number = c.Material_Number 
     LEFT JOIN Table1 a ON a.Procedure_Name = b.Procedure_Name 
    WHERE a.Procedure_Name is null; 

所有的命令都重複比較:

create table Table1 (Procedure_Name char, date date); 
create table Table2 (Procedure_Name char, Material_Number int); 
create table Materials (Material_Name varchar(12), Material_Number int); 

insert into Table1 values ('A', '2012-11-22'); 
insert into Table1 values ('B', '2012-11-21'); 
insert into Table1 values ('C', '2012-11-20'); 

insert into Table2 values ('A', '101'); 
insert into Table2 values ('B', '102'); 
insert into Table2 values ('C', '103'); 
insert into Table2 values ('D', '104'); 
insert into Table2 values ('E', '105'); 

insert into Materials values ('Iron', 101); 
insert into Materials values ('Steel', 102); 
insert into Materials values ('Wood', 103); 
insert into Materials values ('Glass', 104); 
insert into Materials values ('Sand', 105); 

-- johan query 
SELECT Material_Name 
FROM Materials M 
LEFT JOIN Table2 T ON M.Material_Number = T.Material_Number 
WHERE Procedure_Name IS NULL; 

-- my query 
select Material_Name 
    from Materials c 
    left join Table2 b on b.Material_Number = c.Material_Number 
    left join Table1 a on a.Procedure_Name = b.Procedure_name 
where a.Procedure_Name is null; 
+0

這個查詢讓我畏縮了一下 - 兩個不必要的連接!我猜測性能不是問題! NOT IN操作符的設計恰恰是爲了回答用戶提出的問題! –

+0

我建議你在聲明我有「幾乎正確」之前嘗試我的查詢。一個左連接就足夠了 - 第二個完全沒有必要。但是您顯然必須將您的a.Procedue_Name更改爲b.Procedure_Name - 或者直接刪除表格限定符。 –

+0

感謝您的幫助,2 LEFT JOIN幫助:)但謝謝大家花時間幫助^^ – user2965118

3

在表1和表2加入你有它只會給你行所用的材料。你想要做的是選擇所有尚未使用的材料。要做到這一點,只需使用NOT IN構造一個子查詢:

SELECT Material_Name AS Unused_materials 
FROM Materials 
WHERE Materials.Material_Number 
    NOT IN (SELECT Material_Number FROM Table2) 

更新:現在我明白了數據模型(即沒有在表1中列出的程序中使用僅想的材料)這裏是如果使用NOT IN構建查詢使用正確的查詢:

SELECT Material_Name AS Unused_materials 
FROM Materials 
WHERE Materials.Material_Number 
    NOT IN (SELECT Material_Number FROM Table2 
      INNER JOIN Table1 
       ON Table1.Procedure_Name = Table2.Procedure_Name) 
+0

雖然查詢優化器可能會將其轉換爲與使用LEFT JOIN同樣有效的方法,但mysql不會。運行你的查詢和我的解釋,你會看到不同之處。這將爲主要查詢中找到的每一行執行一個子查詢。 Gernal advive:遠離(不)存在和(不)在 –

+0

@johanmårtensson - 這會讓我感到驚訝,因爲我依賴於其他數據庫技術的過去經驗。我必須更多地檢查這一點! –

+0

@johanmårtensson - 這篇文章似乎很適合這些查詢的分析:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql /我仍然認爲,如果假設表格索引合適,NOT IN性能將比平均(如果不是更好)性能好。遠離NOT IN的建議似乎沒有根據,但是,鏈接的文章確實警告不存在!下次我有一個mysql項目時,我必須記住這一點。 –

2

編輯: 忽略此解決方案。爲了進行完整的討論,我放棄了它。或者通常會刪除這個答案?

下大衛Fleeman的解決意見,討論後,我做了一些分析和簡短的回答是:去與大衛Fleemans解決方案,使用NOT IN。這將比左連接解決方​​案更快。

不要使用大衛Fleemans解決方案

原帖 你將永遠不會得到任何東西,但使用該查詢的一個空結果的原因是您選擇material_name,也可以指定material_name爲空...

所有表2中使用的材料將具有條目。所有未使用的材料將缺乏這樣的條目。因此,從材料中選擇,與表格2左連接並添加過程名稱爲空的條件。

SELECT Material_Name 
FROM Materials M 
LEFT JOIN Table2 T ON M.Material_Number = T.Material_Number 
WHERE Procedure_Name IS NULL