以下句子中的用户定义变量是相当有线的,

  SELECT
           @f:=CONVERT(
             IF(@c<=>CatId  AND DATEDIFF(Date, @d)=1, @f, Date), DATE
           ) AS Begin,
           @c:=CatId, @d:=Date
  FROM     my_table  AS init
  ORDER BY CatId, Date


如此处所示:http://sqlfiddle.com/#!2/fddbd/83,而my_table由以下代码给定:

CREATE TABLE my_table (
  Id    INT(6) UNSIGNED ZEROFILL,
  CatId INT,
  Date  DATE,
  Rate  INT
);

INSERT INTO my_table
VALUES
  (000001, 12, '2009-07-07', 1),
  (000002, 12, '2009-07-08', 1),
  (000003, 12, '2009-07-09', 1),
  (000004, 12, '2009-07-10', 2),
  (000005, 12, '2009-07-15', 1),
  (000006, 12, '2009-07-16', 1),
  (000007, 13, '2009-07-08', 1),
  (000008, 13, '2009-07-09', 1),
  (000009, 14, '2009-07-07', 2),
  (000010, 14, '2009-07-08', 1),
  (000010, 14, '2009-07-10', 1);


更准确地说,变量@f不是预定义的,mysql对DateDiff的逻辑是什么?

最佳答案

在第一行,它将使用NULL表示所有变量的值。因此,这等效于以下查询,这些查询将它们全部显式初始化

SELECT
    @f:=CONVERT(
        IF(@c<=>CatId  AND DATEDIFF(Date, @d)=1, @f, Date), DATE
    ) AS Begin,
    @c:=CatId, @d:=Date
FROM my_table  AS init
CROSS JOIN (SELECT @f := NULL, @c := NULL, @d := NULL) AS vars
ORDER BY CatId, Date


通常不建议将ORDER BY子句放在与处理相同的查询级别。 MySQL根据在ORDER BY子句中是否命名SELECT中的列,执行不同的操作。如果是这样,它将在产生所有结果之后执行排序,否则将在处理它们之前使用它对表中的行进行排序。获得可预测结果的方法是使用子查询:

SELECT
    @f:=CONVERT(
        IF(@c<=>CatId  AND DATEDIFF(Date, @d)=1, @f, Date), DATE
    ) AS Begin,
    @c:=CatId, @d:=Date
FROM (SELECT *
      FROM my_table
      ORDER BY CatId, Date)  AS init
CROSS JOIN (SELECT @f := NULL, @c := NULL, @d := NULL) AS vars


由于在不同的MySQL版本上会看到不同的结果,因此这也可能取决于版本。使用子查询应使其始终如一地工作。

关于mysql - mysql SQLselect用户变量如果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28103825/

10-13 01:49
查看更多