【问题标题】:MySQL: Aggregating and GroupingMySQL:聚合和分组
【发布时间】:2016-01-21 11:12:32
【问题描述】:

这里有点 MySQL 和 PHP 的问题。

我有这两张表:

CREATE Table users (
  id BIGINT(100) AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL, 
  password VARCHAR(50) NOT NULL
);

CREATE Table articles (
  id BIGINT(100) AUTO_INCREMENT PRIMARY KEY,
  author_id BIGINT(100) NOT NULL, 
  title VARCHAR(50) NOT NULL, 
  content TEXT, 
  published DATETIME NOT NULL
);

插入:

INSERT INTO users (username, password) 
VALUES ('Bob', '5f4dcc3b5aa765d61d8327deb882cf99');

INSERT INTO users (username, password) 
VALUES ('David', '630bf032efe4507f2c57b280995925a9');

INSERT INTO articles (author_id, title, content, published)
VALUES ('1', 'Science 101', 'Science is the concerted human effort to understand, or to understand better, the history of the natural world and how the natural world works, with observable physical evidence as the basis of that understanding1. It is done through observation of natural phenomena, and/or through experimentation that tries to simulate natural processes under controlled conditions.',
        '2015-11-30 09:18:43');

INSERT INTO articles (author_id, title, content, published)
VALUES ('1', 'Health Care', 'Health care or healthcare is the maintenance or improvement of health via the diagnosis, treatment, and prevention of disease, illness, injury, and other physical and mental impairments in human beings.',
        '2016-01-10 15:20:43');

INSERT INTO articles (author_id, title, content, published)
VALUES ('2', 'Physics 101', 'Physics is a natural science based on experiments, measurements and mathematical analysis with the purpose of finding quantitative physical laws for everything from the nanoworld of the microcosmos to the planets, solar systems and galaxies that occupy the macrocosmos.',
        '2016-01-17 14:18:43');

查询:

SELECT 
  articles.id, 
  articles.author_id,
  users.username,
  COUNT(articles.id) AS number_of_articles,
  GROUP_CONCAT(DISTINCT articles.id) AS articles_published
FROM articles 
LEFT JOIN users ON articles.author_id = users.id
GROUP BY articles.author_id 
ORDER BY articles.published DESC;

结果:

id  author_id   username    number_of_articles  articles_published
3   2           David       1                   3
2   1           Bob         2                   2,1

这是我的 SQLfiddle:http://sqlfiddle.com/#!9/964ed/1

articles_published 列保存如上所示的 id,使用这些 id,我想获取附加信息,例如:属于各自作者的每篇文章的标题和内容。

我在某处读过可以使用explode (PHP),但这只会给你一个ID 数组,而不是我想要的结果。我想要这个汇总,如图所示(参见预期结果部分)。

$r = $result[1]['articles_published']; //2,1 
$array = explode(',',$r);
print_r($array);

//Output:
Array
(
    [0] => 2
    [1] => 1
)

包含爆炸后结果的数组,并不能真正帮助我获得额外的结果,例如:articles 表中 ID 为 1 和 2 的文章的标题和内容。

预期结果:

David wrote 1 article

Physics 101
Physics is a natural science based on experiments, measurements and mathematical analysis with the purpose of finding quantitative physical laws for everything from the nanoworld of the microcosmos to the planets, solar systems and galaxies that occupy the macrocosmos.

-----

Bob wrote 2 articles

Health Care
Health care or healthcare is the maintenance or improvement of health via the diagnosis, treatment, and prevention of disease, illness, injury, and other physical and mental impairments in human beings.

Science 101
Science is the concerted human effort to understand, or to understand better, the history of the natural world and how the natural world works, with observable physical evidence as the basis of that understanding1. It is done through observation of natural phenomena, and/or through experimentation that tries to simulate natural processes under controlled conditions.

------

编辑:是的,至于 MySQL,我知道我可以做到(见下文),但我不打算通过 MySQL 聚合和分组内容。

SELECT users.username
     , articles.title 
     , articles.content
  FROM users
INNER
  JOIN articles 
    ON articles.author_id = users.id
ORDER 
    BY users.username
     , articles.title

【问题讨论】:

  • 您无法从单个查询中获得所需的结果集,您所做的是正确的,但您必须再做一件事来获取文章,您在变量中有文章的 id。 $r = $result[1]['articles_published']; bestway 是编写一个 sql 查询并将该查询中的所有文章凝胶化,以便您可以打印它们。 select * from artiles where id in ($r) 顺便说一下,explode 只将字符串转换为数组,您返回的数据库 2,1 explode 只能拆分它们,您必须代表这些 id 检索数据。不是专业人士,但希望它可以提供帮助。
  • @AmitSarwara,感谢您的回复。我不得不承认,这听起来很愚蠢:“你数据库返回的 2,1 爆炸只能拆分它们,你必须代表这些 id 检索数据。不是专业的,但希望它可以帮助”,因为,我已经知道那,这就是我在这里问的原因,看起来像你 TL;DR 我的问题。至于代码“select * from artiles where id in ($r)”,我也知道,问题是它必须针对数据库循环运行,这非常糟糕。 $r 必须更改下一个要抓取的索引。
  • @johy smith 对不起我的愚蠢。但我也有另一种解决方案。如果您想使用单个查询并希望获得结果。使用子查询来获得您的结果集。
  • @AmitSarwara,解释一下。
  • 像这个查询一样,~SELECT users.username,articles.title,articles.content,(select count(article_id) from items a where a.author_id=users.id) as count FROM users INNER JOIN文章 ONarticles.author_id = users.id ORDER BY users.username,articles.title~ 我们所说的是在数据库的每一行添加一个列名计数,其中包含用户拥有的所有文章的计数张贴。抱歉,实际上是从手机打字的错字

标签: php mysql


【解决方案1】:

两种选择:

第一

运行第二个查询以获取文章数据。

SELECT * FROM `articles` WHERE `id` IN (articles_published)

第二次

在文章标题和内容上也使用GROUP_CONCAT,例如id。用一些不会出现在文章标题或内容中的东西分开。例如:

SELECT 
  articles.id, 
  articles.author_id,
  users.username,
  COUNT(articles.id) AS number_of_articles,
  GROUP_CONCAT(DISTINCT articles.id) AS articles_id,
  GROUP_CONCAT(articles.title SEPARATOR '<--next article-->') AS articles_title,
  GROUP_CONCAT(articles.content SEPARATOR '<--next article-->') AS articles_content
FROM articles 
LEFT JOIN users ON articles.author_id = users.id
GROUP BY articles.author_id 
ORDER BY articles.published DESC;

你的 PHP 会是这个样子。

foreach ($results as $result) {
  $article_ids      = explode(',', $result['articles_id']);
  $article_titles   = explode('<--next article-->', $result['articles_title']);
  $article_contents = explode('<--next article-->', $result['articles_content']);

  echo $result['username'].' wrote '.$result['number_of_articles'].' '.($result['number_of_articles']>1 ? 'articles' : 'article').'<br /><br />';

  foreach ($article_ids as $key => $article_id) {
    $title   = $article_titles[$key];
    $content = $article_contents[$key];

    echo $title.'<br />';
    echo $content.'<br /><br />';
  }

  echo '-----<br />';
}

【讨论】:

  • #1:运行第二个查询以获取文章数据。问题是你必须增加数组[index]['articles_published']的索引,这很糟糕,因为你最终会运行MySQL查询:“SELECT * FROM articles WHERE id IN (articles_published)”在一个循环中,这很糟糕。阿格。
  • 是的,你完全正确。 #1 不好,因为它会循环运行。
  • 如果我理解正确:用户 A 说只要选择 articles.title,结果将是所有结果的第一个标题/内容(并非所有文章都属于作者)。用户 B 基本上是说要使用 GROUP_CONCAT,就像我在 #2 解决方案中所做的那样。
  • 很难说,我看不出你拿这个去哪儿了。但我想,在这种情况下,字段sa.activityIDarticles.titlearticles.content 相同。
  • 与当前案例进行比较:它表示在author_id 上进行分组将丢失所有其他文章的标题和内容(第一个除外)。所以,你必须使用GROUP_CONCAT来获取所有与author_id相关的文章数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
相关资源
最近更新 更多