2010-07-26 107 views
2

我有2個查詢顯示2個不同的值,但來自一個查詢的結果是意外的。MySQL與WHERE子句連接

查詢1:

SELECT SUM(T.amount_reward_user) AS total_grouping 
    FROM fem_user_cards UC 
     LEFT JOIN fem_transactions T USING(card_number) 
     LEFT JOIN fem_company_login FCL 
         ON T.fem_company_login_id=FCL.fem_company_login_id 
    WHERE UC.fem_user_login_id=193 
         AND FCL.grouping<>0 AND T.from_group=1 AND T.authorised=1 
    GROUP BY UC.fem_user_login_id 

上述查詢給我的總回報金額的用戶193.這裏的條件是我收到了該查詢必須來自該組的獎勵金額是顯而易見的來自T.from_group = 1。所以這似乎是正確的。

QUERY2:

SELECT SUM(T.amount_reward_user) AS total_grouping 
    FROM fem_transactions T 
LEFT JOIN fem_company_login FCL 
ON T.fem_company_login_id=FCL.fem_company_login_id 
    WHERE T.fem_user_login_id=193 
     AND FCL.grouping<>0 AND T.from_group=1 AND T.authorised=1 

在該查詢中,即使T.from_group = 1它被從T.from_group = 0相加的獎勵量爲好。有誰知道問題是什麼?

例如:

用戶193購買的東西在一個公司A(該組中,以便T.from_group = 1)爲$ 5,並得到的$ 1獎賞和購買其他產品爲$ 5從公司B(出所以T.from_group = 0),並再次獲得1美元的獎勵。

我的預期成果是:1

我越來越:

查詢1:1

QUERY2:2

我可以簡單地使用查詢1,但我有別的事問題當我使用它,所以我需要了解真正發生了什麼!


我的目標是從數據庫中獲得獎勵金額的總和。總和應該是不同的分組公司。也就是說,如果我們有5個不同的分組公司,並且用戶在這5家公司中使用他的錢卡,我應該得到5個不同的總數。如果他在任何不屬於該組織的公司中使用了他的卡片,則該總額不應包括來自該未分組公司的交易。當事務發生時,我有C++代碼來提供數據庫。我的fem_transactions表有company_id,amount_reward_user,fem_user_login_id,from_group(這決定了用戶是否從組或團隊中進行交易),授權等。

我想篩選用戶193在每個分組。

我現在理解JOINTS概念,但我需要知道爲什麼t.from_group在第二個查詢上被忽略?

+1

你將不得不發佈一些示例數據和輸出說明問題,隨着你期望輸出是什麼。請編輯您的問題並添加此信息。 – 2010-07-26 18:37:21

+0

我不知道它是否能解決您的問題,但您需要更好地理解左連接和where子句。這個是SQL Server特有的,但saame原則應該適用於所有數據庫: http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN – HLGEM 2010-07-26 18:39:50

+0

您應該編輯原始帖子,而不是發佈回覆。另外,我們需要看一些表格模式。我不確定這個分組是如何適合這個公司的。 – Thomas 2010-07-27 14:52:37

回答

2

問題是您在Where子句中對左連接右側的列有條件。在這兩個查詢中,這是And FCL.grouping <> 0。這有效地將左連接更改爲內連接,因爲您要求存在FCL.grouping值而不是零(或Null)。你想,我想什麼,方法是把標準納入ON子句:

首先查詢:

Select Sum(T.amount_reward_user) AS total_grouping 
From fem_user_cards UC 
    Left Join fem_transactions T Using(card_number) 
    Left Join fem_company_login FCL 
     On FCL.fem_company_login_id = T.fem_company_login_id 
      And FCL.grouping<>0 
Where UC.fem_user_login_id=193 
    And T.from_group=1 
    And T.authorised=1 
Group By UC.fem_user_login_id 

第二個查詢

Select Sum(T.amount_reward_user) AS total_grouping 
From fem_transactions T 
    Left Join fem_company_login FCL 
     On FCL.fem_company_login_id = T.fem_company_login_id 
      And FCL.grouping<>0 
Where UC.fem_user_login_id=193 
    And T.from_group=1 
    And T.authorised=1 

是什麼並不清楚這一切的是什麼你正在努力實現。即,爲什麼即使在兩個查詢中都有左連接,如果你沒有對它們進行篩選。如果您確實想要篩選具有fem_company_login值並且分組值<> 0的行,請使用原始查詢並將左連接更改爲內部連接。如果你想過濾的人,要麼有一個分組值<> 0或根本沒有價值可言,然後做一些事情,如:

Select Sum(T.amount_reward_user) AS total_grouping 
From fem_transactions T 
    Left Join fem_company_login FCL 
     On FCL.fem_company_login_id = T.fem_company_login_id 
Where UC.fem_user_login_id=193 
    And T.from_group=1 
    And T.authorised=1 
    And (FCL.PrimaryKeyColumn Is Null Or FCL.grouping <> 0) 
+0

我並不知道where子句可能會改變連接的含義。我認爲語義是連接的行爲就像創建虛擬表一樣,使用連接條件,然後將where子句應用於該虛擬表。你能否引用你對行爲的描述? – 2010-07-26 21:25:39

+0

@Jim Garrison - 加入的性質就是這樣。當您使用左連接時,您要求左側的所有項目和右側的任何匹配項目。如果您然後在右邊的一個表中的列的Where子句中應用過濾器,並且不考慮Null,則您請求值A.存在,B.不爲空,並且C.符合條件(即相等,不等於,大於等等,取決於操作員)。因此,條件'FCL.grouping <> 0'表明FCL中的一行必須存在,它必須有一個非空的分組值,並且該值不能等於0. – Thomas 2010-07-26 22:17:39

+0

@Jim Garrison - 繼續,如果您應用過濾器這要求在左連接的右側存在一行,您實際上正在進行內連接。 – Thomas 2010-07-26 22:18:38