带GROUP BY的LEFT JOIN返回意外结果

时间:2017-05-10 12:24:44

标签: mysql group-by left-join mariadb

我正在尝试使用以下查询选择feeheads表中不存在的所有st_annual,但它只返回一行,而我希望得到两行:

SELECT A.*
FROM hl_annual A
LEFT JOIN (
        SELECT feeid, regd, class
        FROM st_annual
        GROUP BY regd, feeid
) B ON A.id = B.feeid AND A.class=B.class         
WHERE A.class='4' AND A.session='2'
AND B.feeid IS NULL

请查看fiddle。我希望得到id = 3和id = 6,但我只得到id = 3。

我想选择st_annual表中存在的所有不同的feeid,我想与hl_annual表中的id进行比较。如果我们按照regd和feeid对st_table进行分组时不存在feeid,我想从hl_annual表中获取该缺席费用id。所以从小提琴开始,我得到的只是费用3而不是st_annual,但是我想得到费用= 6,因为这在st_annual的一个regd中不存在。

2 个答案:

答案 0 :(得分:1)

为什么要使用聚合?这是一个想法:使用not exists。对你的意图更加明确,它应该有更好的表现(st_annual(fee_id, class)指数帮助):

SELECT A.*
FROM hl_annual A
WHERE A.class = 4 AND A.session = 2 AND
      NOT EXISTS (SELECT 1
                  FROM st_annual sa
                  WHERE A.id = sa.feeid AND sa.class = B.class
                 )  ;    

我不确定这是否解决了逻辑问题,但它是一个更好的解决问题的地方。

答案 1 :(得分:1)

做出大量假设后......

我们需要一份应该出现的班级和费用的主清单。首先,我们从ST_Annual表中获取一个不同的列表,并加入回HL_Annual;但由于这不包含每个类的regD,我们必须交叉连接以获取每个类的regD现在我们有了主列表,我们将它连接回ST_Annual以找到缺少的。

SELECT A.*,  B.FeeID, c.regd
FROM HL_ANNUAL A
LEFT JOIN (SELECT distinct Y.class, FeeID, Z.RegD
            from ST_ANNUAL Y
            cross join (Select Distinct regD, Class from st_Annual) Z
            WHERE Y.Class = Z.Class
          ) B
  on A.ID = B.FeeID
 and A.Class = B.Class
LEFT JOIN ST_ANNUAL C
  on C.FeeID = B.FeeID
 and C.Class= B.Class
 and C.RegD = B.RegD
WHERE A.class = 4 
  AND A.session = 2
  AND C.RegD is null
Order by A.ID, A.Class

我不禁觉得我们错过了与班级相关的表格,这会让这个更容易,特别是一个表格,这是一个表格与regd之间的关系,也许会话再次我做出假设;对于每个条目。

因为我无法让SQL FIDDLE工作......工作...... http://rextester.com/SMG32021

奇怪表格已经存在...具有相同的数据...

哦......和输出:

    id  class   session feehead             amount  FeeID   regd
  1 3   4       2       Examination Fees    500     NULL    NULL
  2 6   4       2       Sports              1500    6       NULL

但我再次提醒你,我必须对涉及类,regd和session以及id / feeid的数据之间的关系做出几个假设......如果我的假设是错误的;那么这里返回正确的结果,如果数据变化,可能无法返回正确的结果。