【问题标题】:Exact SQL query returns different data using MySQL Command Line and PHP PDO精确的 SQL 查询使用 MySQL 命令行和 PHP PDO 返回不同的数据
【发布时间】:2015-05-30 20:50:57
【问题描述】:

我有一个查询,它从数据库中返回最近 10 条新闻和最近 10 条 cmets。

SQL:

CREATE TABLE news (
  news_id INT UNSIGNED AUTO_INCREMENT,
  subject VARCHAR(128) NOT NULL,
  article TEXT NOT NULL,
  type_id TINYINT UNSIGNED NOT NULL DEFAULT 1,
  news_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (news_id)
);

CREATE TABLE comments (
  comment_id INT UNSIGNED AUTO_INCREMENT,
  message TEXT NOT NULL,
  news_id INT UNSIGNED NOT NULL,
  msg_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (comment_id),
  CONSTRAINT fk_comments_news_id FOREIGN KEY (news_id)
    REFERENCES news (news_id)
    ON DELETE CASCADE
);

SELECT news_id, comment_id, rnk
FROM (
  SELECT
    *,
    @rnk:=IF(@prev_news_id=news_id, @rnk+1, 1) rnk,
    @prev_news_id:=news_id
  FROM (
    SELECT
      lastnews.*,
      cmts.comment_id,
      cmts.message,
      cmts.msg_time
    FROM (SELECT * FROM news WHERE type_id=5 ORDER BY news_id DESC LIMIT 10) lastnews
      LEFT OUTER JOIN comments cmts ON cmts.news_id=lastnews.news_id
    ORDER BY cmts.news_id DESC, cmts.comment_id DESC) t1) t2
WHERE rnk <= 10;

PHP:

$query = <<<_END
SELECT news_id, comment_id, rnk
FROM (
  SELECT
    *,
    @rnk:=IF(@prev_news_id=news_id, @rnk+1, 1) rnk,
    @prev_news_id:=news_id
  FROM (
    SELECT
      lastnews.*,
      cmts.comment_id,
      cmts.message,
      cmts.msg_time
    FROM (SELECT * FROM news WHERE type_id=5 ORDER BY news_id DESC LIMIT 10) lastnews
      LEFT OUTER JOIN comments cmts ON cmts.news_id=lastnews.news_id
    ORDER BY cmts.news_id DESC, cmts.comment_id DESC) t1) t2
WHERE rnk <= 10;
_END;

$db = new PDO('mysql:='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
$dbh = $db->prepare($query);
$dbh->execute();
$data = $dbh->fetchAll(PDO::FETCH_NUM|PDO::FETCH_GROUP);
print_r($data);

查询在 MySQL cmd 中完美运行,但在 PHP 中返回错误数据。问题出在 rnk 行。它总是等于 1。为什么会这样?

更新:我刚刚重新启动 MySQL 命令行,它甚至在那里打破了。但后来我打开了SET profiling=1 的分析,突然它又可以工作了。更重要的是,关闭分析并不会消除效果。

【问题讨论】:

  • 愚蠢的问题,但你确定你正在查看数组的值而不是它的索引吗?
  • 我 100% 确定。它返回所有 rnk=1 的 cmets。我在WHERE rnk &lt;= 10 中设置什么并不重要;

标签: php mysql pdo


【解决方案1】:

原来问题出在用户定义的变量初始化上。我们应该明确地这样做以避免未定义的行为。 在我们的例子中,我们再添加一个连接:

FROM (SELECT * FROM news WHERE type_id=5 ORDER BY news_id DESC LIMIT 10) lastnews
  LEFT OUTER JOIN comments cmts ON cmts.news_id=lastnews.news_id
  INNER JOIN (SELECT @rnk:=0,@prev_news_id:=0) t3

【讨论】:

    猜你喜欢
    • 2013-11-06
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2013-09-07
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多