Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Mysql限制列值重复N次_Php_Mysql_Group By - Fatal编程技术网

Php Mysql限制列值重复N次

Php Mysql限制列值重复N次,php,mysql,group-by,Php,Mysql,Group By,我有两张桌子 Customer (idCustomer, ecc.. ecc..) Comment (idCustomer, idComment, ecc.. ecc..) 例如,显然这两个表是连接在一起的 SELECT * FROM Comment AS co JOIN Customer AS cu ON cu.idCustomer = co.idCustomer 使用此选项,我从与is Customer关联的表中选择所有注释,但现在我想将每个客户的注释数限制为最多2条 我看到的第一件

我有两张桌子

Customer (idCustomer, ecc.. ecc..)
Comment (idCustomer, idComment, ecc.. ecc..)
例如,显然这两个表是连接在一起的

SELECT * FROM Comment AS co
  JOIN Customer AS cu ON cu.idCustomer = co.idCustomer
使用此选项,我从与is Customer关联的表中选择所有注释,但现在我想将每个客户的注释数限制为最多2条

我看到的第一件事是使用GROUP BY cu.idCustomer,但它限制每个客户只有1条评论,但我希望每个客户有2条评论


如何实现这一点?

MySQL中的一个选项是服务器端变量。例如:

set @num := 0, @customer := -1;

select  *
from    (
        select  idCustomer
        ,       commentText
        ,       @num := if(@customer = idCustomer, @num + 1, 1) 
                    as row_number
        ,       @customer := idCustomer
        from    Comments
        order by 
                idCustomer, PostDate desc
        ) as co
join    Customer cu
on      co.idCustomer = cu.idCustomer
where   co.row_number <= 2

此版本不需要设置操作:

select  *
from    (select  idCustomer
         ,       commentText
         ,       @num := if(@customer = idCustomer, @num + 1, 1) as row_number
         ,       @customer = idCustomer
         from    Comments
         JOIN(SELECT @num := 0, @customer := 1) r
         order by idCustomer, PostDate desc) as co
 join    Customer cu on co.idCustomer = cu.idCustomer
 where   co.row_number <= 2

但是,如果要更改注释的数量,最好使用的解决方案。

不需要使用游标,这非常缓慢。看看我对你的回答。DENSE_RANK将在没有所有光标复杂性的情况下完成这项任务。

如果您使用PHP等脚本语言来处理结果,则可以在运行查询后限制每个客户显示的结果数。设置一个数组以保存所有结果,设置另一个数组以保存每个客户的结果数,并在计数超过限制后停止向结果集中添加查询结果,如下所示:

$RESULTS = array();
$COUNTS = array();
$limit = 2;
$query = "SELECT customer_id, customer_name, customer_comment FROM customers ORDER BY RAND()";
$request = mysql_query($query); 
while ($ROW = mysql_fetch_assoc($request))
{
    $c = $ROW['customer_id'];
    $n = $COUNTS[$c];
    if ($n<$limit)
    {
         $RESULTS[] = $ROW;
         $COUNTS[$c]++;
    }
}

这保证了每个客户只显示两条评论,或者随机抽取,或者不管你想怎么做,其余的都会被丢弃。当然,您正在提取所有结果,但这可能比执行复杂联接更快。

似乎没有其他不同的方式。。我对此有点难过。。我看到很多例子,但似乎这是最好的解决方案。我接受它,带着一点悲伤,我更喜欢一个更优雅的解决方案:在这种模式下提取数据,你建议一个不同或更好的数据库布局?@Paper-bat:其他数据库支持更优雅的解决方案。但是MySQL在子查询中存在限制问题,并且不支持行数。您的数据库布局很好,我认为这行@customer=idCustomer不应该是@customer:=idCustomer??mh。。不错在我的国家,意大利将其命名为“BarbarTrucco”:P将其翻译为一个聪明的技巧^^^我只想使用sql查询,因为它在读取代码时更快、更清晰,并且当您将来需要更新代码时,您只需修改sql,只需对脚本代码进行少量更改。这就是为什么我在创建sql查询、更具体的查询、更少的代码时会花费大量时间,最终您可以学到一些新的东西,谢谢您的贡献
$RESULTS = array();
$COUNTS = array();
$limit = 2;
$query = "SELECT customer_id, customer_name, customer_comment FROM customers ORDER BY RAND()";
$request = mysql_query($query); 
while ($ROW = mysql_fetch_assoc($request))
{
    $c = $ROW['customer_id'];
    $n = $COUNTS[$c];
    if ($n<$limit)
    {
         $RESULTS[] = $ROW;
         $COUNTS[$c]++;
    }
}