【问题标题】:how to remove duplicated columns and group column如何删除重复的列和组列
【发布时间】:2014-05-27 09:51:49
【问题描述】:

大家好,我目前有一个运行良好的 MySQL 查询,但我唯一不喜欢的是,当我收到返回的数据时,除了行的最后一列之外,有些行会重复。

我猜是因为当我选择包括左连接在内的所有内容时,commenttext 列包含用户提交的帖子的数据。

例如)如果我发布了一个 id 为 1 的帖子,并且有 5 个人对该帖子发表评论,MySQL 查询将显示 5 行,每列中的所有数据都相同,除了最后一列包含与邮政。

到目前为止,这是我的 MySQL 查询。我怎样才能使它不带回重复的数据,而只带回与帖子的 id 分组的 cmets,或者如何将所有 cmets 存储到一个数组中,这样当我运行 foreach 循环时,我就可以运行 cmets 数组里面有一个while循环。我使用 foreach 循环的原因是使用 html 导出数据。

SELECT
    b.id
    , b.from_user
    , b.dateadded
    , b.posttype
    , b.posttext
    , b.photoname
    , b.blahchoice
    , b.commentschoice
    , b.mood
    , c.defaultphoto
    , d.firstn
    , d.lastn
    , e.status
    , f.topostid
    , f.commenttext 
FROM
    t_board b 
INNER JOIN
    t_userprofiles c ON b.from_user = c.user_id  
INNER JOIN
    t_users d ON b.from_user = d.id
INNER JOIN
    t_friendship e ON e.friend_ids = b.from_user
LEFT JOIN
    t_postcomments f ON f.topostid = b.id
WHERE
    e.status = 'Friend' 
    AND e.user_ids = :id
ORDER BY
    b.id DESC

【问题讨论】:

  • 您能否更好地格式化查询?另外,您可能想创建一个SQL fiddle 供我们使用
  • 你为什么不直接运行多个查询然后在 php 中执行呢?
  • 我做到了,但我想让 ajax 更容易一次获取 @Aliendroid
  • 我不影响你的ajax,没有人说你只能在一次调用中运行一个查询。 @this.Tony

标签: php mysql


【解决方案1】:

一种方法是group_concat() cmets,当您在循环内运行时explode() cmets 然后执行foreach 以在 id 下显示 cmets

SELECT b.id, 
b.from_user, 
b.dateadded, 
b.posttype, 
b.posttext, 
b.photoname, 
b.blahchoice, 
b.commentschoice, 
b.mood, 
c.defaultphoto, 
d.firstn, 
d.lastn, 
e.status, 
f.topostid, 
group_concat(f.commenttext) as  commenttext
FROM t_board b 
INNER JOIN t_userprofiles c ON b.from_user = c.user_id  
INNER JOIN t_users d ON b.from_user = d.id
INNER JOIN t_friendship e ON e.friend_ids = b.from_user
LEFT JOIN t_postcomments f ON f.topostid = b.id
WHERE e.status = 'Friend' 
AND e.user_ids = :id
group by b.id
ORDER BY b.id DESC

注意,当您在 PHP commenttext 上执行查询时,将全部用逗号分隔并在循环内获取每个 b.id 的数据,您将拥有该 id 的所有 cmets 作为逗号分隔的字符串,您可以分解它以生成另一个数组并显示它们。

您的某些 cmets 中可能包含逗号,因此您可能需要为 group_concat 提供分隔符,如下所示,或者可以选择任何自定义运算符。

group_concat(f.commenttext SEPARATOR '||' ) as  commenttext

用 || 分解数据

注意:结果被截断为由下式给出的最大长度 group_concat_max_len 系统变量,默认值为 1024 http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

【讨论】:

  • 如果任何 cmets 包含逗号,这将无法正常工作。您需要指定一个不会出现在任何 cmets 中的分隔符。您可能需要将group_concat_max_len 设置得非常大以避免截断。
  • 是的,我正要更新答案,我已经更新了。
  • 不,您不需要更改 DB 列中的任何内容,因为数据是在选择时连接的,但是如果注释大小真的很大,那么您可能需要更改 mysql 设置以增加group_concat_max_len 值变大,重启mysql。如果您的 cmets 很小并且在 concat 之后它小于 1024 个字符,则不需要它。配置文件在 debian 和 windows WAMP 中的 /etc/mysql/my.cf 上,您可以通过 GUI 修改它。
  • 我测试了它的效果很好,现在说我想获取评论的数据,我将如何处理,比如谁发表了评论以及发表评论的时间?
  • 嗯,我想这不适用于此查询,因为它是一对多的,并且您将留下多行,即对于每个评论,您将拥有一行。并且 cmets 以及用户和日期时间也可以连接,但这需要子查询来执行操作。
【解决方案2】:

在您的 PHP 提取循环中合并同一帖子的条目:

$results = array();
while ($row = $stmt->fetch()) {
    if (isset($results[$id]) {
        $results[$id]['comments'][] = $row['commenttext'];
    } else {
        $row[$id] = $row;
        $row['comments'] = array($row['commenttext']);
    }
}

【讨论】:

    猜你喜欢
    • 2019-04-23
    • 2019-07-02
    • 1970-01-01
    • 2017-02-23
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    相关资源
    最近更新 更多