2010-07-26 3 views
2

У меня есть 2 запроса, которые отображают 2 разных значения, но результаты одного запроса неожиданны.MySQL присоединяется к предложению WHERE

Query1:

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 купил что-то в компании А (в группе, так T.from_group = 1) за $ 5 и получил вознаграждение в размере $ 1 и купил еще один продукт за $ 5 от компании B (из группы, так что T.from_group = 0) и снова получите вознаграждение в размере 1 доллара.

Мой ожидаемый результат: 1

Я получаю:

Query1: 1

QUERY2: 2

я мог бы просто использовать запрос 1, но у меня есть проблемы с другими вещами когда я использую это, поэтому мне нужно понять, что происходит на самом деле!


Моя цель - получить сумму суммы вознаграждения из базы данных. Сумма должна быть разной группы компаний. То есть, если у нас есть 5 разных сгруппированных компаний, и пользователь использует свой moneycard в этих 5 компаниях, я должен получить 5 разных итогов. Если он использовал свою карточку в любой компании, которая не входит в группу, то сумма не должна включать транзакцию от этой негруппированной компании. У меня есть код C++ для подачи базы данных по мере совершения транзакций. В моей таблице fem_transactions есть company_id, amount_reward_user, fem_user_login_id, from_group (это решает, был ли пользователь выполнен из группы или из группы), разрешено и т. Д.

Я хочу отфильтровать сумму, потраченную пользователем 193 в каждом группы отдельно.

Теперь я понял концепции JOINTS, но мне нужно знать, почему t.from_group по второму запросу игнорируется?

+1

Вы должны опубликовать некоторые выборочные данные и выходные данные, демонстрирующие проблемы, наряду с что вы ожидаете от вывода. Измените свой вопрос и добавьте эту информацию. –

+0

Я не знаю, будет ли это исправлять вашу проблему, но вам нужно лучше понять левые соединения и предложения. это один из SQL Server, но принцип saame может быть применим ко всем базам данных: http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN – HLGEM

+0

Вы должны отредактировать исходный пост, а не опубликовать ответ. Кроме того, нам нужно увидеть схему таблиц. Я не уверен, как группировка вписывается в группу компании. – Thomas

ответ

2

Проблема в том, что у вас есть критерии в предложении Where против столбцов в правой части левого соединения. В обоих запросах это And FCL.grouping <> 0. Это эффективно изменяет Left Join на Inner Join, поскольку вы требуете, чтобы значение FCL.grouping существовало и не было равным нулю (или Null). То, что вы хотите, я думаю, заключается в переходе, что критерии в предложении О:

Первый запрос:

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, используйте исходный запрос и измените Left Join на Inner Join. Если вы хотите, чтобы фильтр для людей, которые либо имеют значение группировки <> 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'. Можете ли вы привести ссылку для описания поведения? –

+0

@Jim Garrison - Это в природе Join, что он работает именно так. Когда вы используете Left Join, вы запрашиваете все элементы слева и любые соответствующие элементы справа. Если затем применить фильтр в предложении Where в столбце из таблицы справа и не учитывать Null, вы запрашиваете, чтобы значение A. Exist, B. не было нулевым и C. соответствовало критериям (т.е. равным, не равным, большим и т. д. в зависимости от оператора). Таким образом, критерии «FCL.grouping <> 0' заявляют, что строка из FCL должна существовать, она должна иметь ненулевое значение группировки, и это значение не должно равняться 0. – Thomas

+0

@Jim Garrison - Продолжение, если вы применяете фильтр который требует, чтобы строка с правой стороны Left Join существовала, вы фактически создаете Inner Join. – Thomas

Смежные вопросы