MySQL与WHERE子句连接

MySQL与WHERE子句连接,sql,mysql,phpmyadmin,aggregate-functions,Sql,Mysql,Phpmyadmin,Aggregate Functions,我有两个查询,其中显示了两个不同的值,但一个查询的结果是意外的 问题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_

我有两个查询,其中显示了两个不同的值,但一个查询的结果是意外的

问题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
选择总和(T.金额\奖励\用户)作为总分组
来自fem_用户卡UC
使用(卡号)左连接fem\u事务
左连接有限元公司登录FCL
在T.fem_company_login_id=FCL.fem_company_login_id上
其中UC.fem\u user\u login\u id=193
FCL.grouping0和T.from_group=1和T.authorized=1
按UC.fem用户登录id分组
上面的查询给出了用户193的总奖励金额。这里的条件是我从这个查询中得到的奖励金额必须来自于组,这从T.from_group=1可以明显看出。所以这似乎是正确的

问题2:

   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.金额\奖励\用户)作为总分组
从fem_T
左连接有限元公司登录FCL
在T.fem_company_login_id=FCL.fem_company_login_id上
其中T.fem\u用户\u登录\u id=193
FCL.grouping0和T.from_group=1和T.authorized=1
在这个查询中,即使T.from_group=1,它也将T.from_group=0的奖励金额相加。有人知道问题出在哪里吗

例如:

用户193以5美元的价格在a公司(在so T.from_group=1组中)购买了一些东西,获得了1美元的奖励,并以5美元的价格从B公司(在so T.from_group=0组外)购买了另一种产品,再次获得了1美元的奖励

我的预期产出是:1

我得到:

问题1:1

问题2:2

我可以简单地使用查询1,但是当我使用它时,我会遇到其他问题,所以我需要了解到底发生了什么


我的目标是从数据库中获取奖励金额的总和。金额应为不同分组公司的金额。也就是说,如果我们有5个不同的分组公司,并且用户在这5个公司使用他的货币卡,我应该得到5个不同的总数。如果他在集团以外的任何公司使用信用卡,则总额不应包括该未分组公司的交易。在事务发生时,我有C++代码来给数据库提供数据。我的fem_交易表具有公司id、金额奖励用户、fem_用户登录id、来自组(这决定用户是从组外还是从组内进行交易)、授权等

我想分别过滤每个组中用户193花费的金额


我现在理解了连接的概念,但我需要知道为什么第二个查询中的t.from_group被忽略?

问题是Where子句中有针对左连接右侧列的条件。在这两个查询中,这是
和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

您必须发布一些示例数据和输出来演示问题,以及您期望的输出。请编辑您的问题并添加此信息;我不知道它是否能解决您的问题,但您需要更好地理解左连接和where子句。这是特定于SQL Server的,但saame原则应该适用于所有数据库:您应该编辑原始帖子,而不是发布响应。此外,我们需要查看一些表模式。我不确定该分组如何与公司的分组相匹配。我不知道
where
子句会改变连接的含义。我认为语义是连接的行为就像使用连接条件创建了一个虚拟表一样,然后将
where
子句应用于该虚拟表。你能举出一个参考来描述你的行为吗?@Jim Garrison-这是连接的本质,它是这样工作的。当您使用左联接时,您会要求左侧的所有项目和右侧的任何匹配项目。如果您随后在右侧表格中的列上的Where子句中应用筛选器,并且不考虑Null,则您请求值a.存在,B.不为Null,C.匹配条件(即,根据运算符的不同,相等、不相等、大于等)。因此,条件
FCL.grouping 0
说明FCL中的一行必须存在,它必须有一个非空的分组值,并且该值不能等于0。@Jim Garrison-如果应用的筛选器要求左连接右侧的一行存在,则继续,你实际上是在做一个内部连接。你能告诉我这在规范中是怎么描述的吗?我的理解是,虚拟表包含来自缺失行的数据的空值(与内部联接相反,在内部联接中根本没有虚拟行)。
where
子句只看到null,不应更改连接的含义。如果您能在任何SQL规范中找到描述这一点的地方,这将非常有帮助。@Jim Garrison-您是正确的,因为左联接中的右表将包含缺失行的空值。但是,随后您将返回并过滤掉Where子句中缺少的行。标准
FCL.Grouping 0
相当于写入
(FCL.Grouping不为空,FCL.Grouping 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
            And FCL.grouping<>0
Where UC.fem_user_login_id=193 
    And T.from_group=1 
    And T.authorised=1
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 )