【问题标题】:Complex SQL query JOIN and WHERE复杂的 SQL 查询 JOIN 和 WHERE
【发布时间】:2013-05-09 15:20:35
【问题描述】:

我有一张桌子,我需要从中获取联系人。所以我使用一个复杂的查询来从我的“sms”表中检索所有的联系人。

但是,它应该只计算提供的“imei”字段的记录,但我的查询会不断返回特定联系人的所有计数。

下面是使用代码:

$sql = $this->db->query('
    SELECT 
        t1.mnumber AS t1_number, t1.mcontent AS t1_content, t1.mcontact as t1_contact, SUM(t2.TOTAL) AS mTotal
    FROM
        sms t1
            JOIN
        (SELECT 
            mContent, mcontact, COUNT(mNumber) AS TOTAL, mnumber, MAX(mID) mID
        FROM
            sms
        GROUP BY mContact) t2 ON t1.mcontact = t2.mcontact
            AND t1.mid = t2.mid
        WHERE t1.mIMEI = ' . (IMEI) . '
        GROUP BY t1.mContact
        ORDER BY t1.mid DESC');

    return $sql->result();

【问题讨论】:

  • 当未在组中指定 SELECT 列表中的所有列时,请注意在 MySQL 中使用 GROUP BY。您的结果可能不确定...
  • 您的WHERE 子句在内部子查询执行其计数之后进行评估。

标签: php mysql sql codeigniter join


【解决方案1】:

格式更好,查询是:

SELECT t1.mnumber AS t1_number, t1.mcontent AS t1_content, t1.mcontact as t1_contact, SUM(t2.TOTAL) AS mTotal
FROM sms t1 JOIN
     (SELECT mContent, mcontact, COUNT(mNumber) AS TOTAL, mnumber, MAX(mID) mID
      FROM sms
      GROUP BY mContact
     ) t2
     ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
WHERE t1.mIMEI = ' . (IMEI) . '
GROUP BY t1.mContact
ORDER BY t1.mid DESC

问题是where 子句放错了地方。要让它影响计数,您需要在子查询中使用它。要使其影响输出行,您需要在外部查询中使用它。我建议:

SELECT t1.mnumber AS t1_number, t1.mcontent AS t1_content, t1.mcontact as t1_contact, SUM(t2.TOTAL) AS mTotal
FROM sms t1 JOIN
     (SELECT mContent, mcontact, COUNT(mNumber) AS TOTAL, mnumber, MAX(mID) as maxmid
      FROM sms
      WHERE sms.mIMEI = ' . (IMEI) . '
      GROUP BY mContact
     ) t2
     ON t1.mcontact = t2.mcontact AND t1.mid = t2.maxmid
GROUP BY t1.mContact
ORDER BY t1.mid DESC

我怀疑可能还有其他简化,具体取决于midmcontact 在数据库结构方面的含义。

【讨论】:

  • 谢谢,我注意到 :) 但是,它仍然给我返回错误的计数。例如,对于 IMEI 0123,联系人 X 的计数为 12。在通用表中,X 的总计数为 40。当我执行查询时,结果是 40 而不是 12。
  • @SamNapkins:谢谢,但还是同样的问题?
【解决方案2】:

您需要在两个SELECT 语句中使用WHERE 子句。

SELECT t1.mnumber AS t1_number, t1.mcontent AS t1_content, t1.mcontact as t1_contact, SUM(t2.TOTAL) AS mTotal
FROM sms t1 JOIN
     (SELECT mContent, mcontact, COUNT(mNumber) AS TOTAL, mnumber, MAX(mID) mID
      FROM sms
      WHERE mIMEI = ' . (IMEI) . '
      GROUP BY mContact
     ) t2
     ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
WHERE t1.mIMEI = ' . (IMEI) . '
GROUP BY t1.mContact
ORDER BY t1.mid DESC

如果在这两个地方都没有WHERE 子句,您将加入与mContact 匹配的所有记录。即使是那些不符合您t1.mIMEI = ' . (IMEI) . ' 条件的。

【讨论】:

    【解决方案3】:

    @Gordon Linoff 给出的答案是正确的。 然而真正的问题在于表格本身。

    它存储所有消息,但有时“mNumber”是国际电话号码,有时它是用户存储到手机的格式。

    因此,当我使用“mNumber”字段加载“mContent”时,它只会给我一个部分结果!!

    所以还在寻找解决方案吗?也许是多个 WHERE 分句?

    【讨论】:

      猜你喜欢
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      相关资源
      最近更新 更多