0

几个小时以来一直在努力解决这个问题的一个版本,我知道这可能是我缺少的一些东西。

我有一个基于这篇文章的第一个答案的查询:

如何限制 SQL 中每个字段值的行数?

这正是我希望它在 MySQL Workbench 中执行的操作,但在从以下位置运行时不会将会话变量设置为“2”:

mysql_query()

在 PHP 中。

下面是一个表格,“mytab”,它演示了这个问题:

+----+--------------+---------------+
| id | first_column | second_column |
+----+--------------+---------------+
|  1 |            1 |             1 |
|  2 |            1 |             4 |
|  3 |            2 |            10 |
|  4 |            3 |             4 |
|  5 |            1 |             4 |
|  6 |            2 |             5 |
|  7 |            1 |             6 |
+----+--------------+---------------+

和一个简化的查询:

select
    id, first_column, second_column, row_num
from 
(
    select *,
    @num := if(@first_column = first_column, 2, 1) as row_num,
    @first_column := first_column as c
    from mytab order by first_column,id
) as t
having row_num <= 1; 

从 MySQL 工作台我得到这个:

+----+--------------+---------------+---------+
| id | first_column | second_column | row_num |
+----+--------------+---------------+---------+ 
|  1 |            1 |             1 |       1 |
|  3 |            2 |            10 |       1 |
|  4 |            3 |             4 |       1 |
+----+--------------+---------------+---------+

从 PHP 我得到这个:

+----+--------------+---------------+---------+
| id | first_column | second_column | row_num |
+----+--------------+---------------+---------+
|  1 |            1 |             1 |       1 |
|  2 |            1 |             4 |       1 |
|  3 |            2 |            10 |       1 |
|  4 |            3 |             4 |       1 |
|  5 |            1 |             4 |       1 |
|  6 |            2 |             5 |       1 |
|  7 |            1 |             6 |       1 |
+----+--------------+---------------+---------+

难道我做错了什么?

非常感谢!


编辑:这是我精简的 PHP 代码,因为现实中的问题与一些更复杂的东西有关。

class sql_helper extends other
{
    public function query_handler($sql, $error_message) 
    {
        $this->connect(); // Not shown, but works without issue

        $result = mysql_query($sql) or die($error_message.''.mysql_error());

        return $result;
    }

    public static function sql_result_to_assoc($sql_result) 
    {
        $result_array = array();

        while($row = mysql_fetch_assoc($sql_result))
            $result_array[] = $row;

        return $result_array;
    }

    public function sql_to_assoc($sql, $error_message)
    {
        $result = $this->query_handler($sql, $error_message);

        return $this->sql_result_to_assoc($result);
    }
}

$sql = "
    select
    id, first_column, second_column, row_num
    from 
    (
        select *,
        @num := if(@first_column = first_column, 2, 1) as row_num,
        @first_column := first_column as c
        from mytab order by first_column,id
    ) as t
    having row_num<=1";

$sql_helper   = new sql_helper();
$result_array = $sql_helper->sql_to_assoc($sql, '');
4

2 回答 2

2

您需要初始化会话变量:

SET @num:=0;
SET @first_column:=0;

这必须在同一个 MySQL 会话中并且在您的查询之前完成。

于 2013-07-02T08:31:29.700 回答
1

正如 Jerahian 回答的那样,他们需要在同一个会话中。我通常会进行内联声明,但您必须将其包装为一个选择并分配一个“别名”,例如

select
    id, first_column, second_column, row_num
from 
   ( select *,
           @num := if(@first_column = first_column, 2, 1) as row_num,
           @first_column := first_column as c
        from 
           mytab,
           ( select @first_column := 0 ) as Sqlvars
      order by 
           first_column,
           id
   ) as t
having 
   row_num <= 1; 

注意 @first_column := 0 作为“sqlvars”别名的非常微妙的初始化......然后它可以按照您的意图使用。如果您有多个变量,只需像其他列一样用逗号分隔......例如

   ( select @first_column := 0, 
            @someOtherField := '2013-06-02',
            @someString := 'testing' ) as Sqlvars
于 2013-07-02T10:15:03.913 回答