2015-01-23 2 views
0

ли вполне проводной, что определяемая пользователем переменная в следующем предложении,Mysql SQLSelect пользователем переменной, если

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?

+0

и что такое '<=>' означает? почему просто «<>»? –

+0

Это нейтральный оператор равенства. http://dev.mysql.com/doc/refman/5.0/ru/comparison-operators.html#operator_equal-to – Barmar

+0

@Barmar Я вижу это, по сути, сначала я думаю, что он равен '<>', какое большое недоразумение! Благодаря! –

ответ

1

В первой строке он будет использовать 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, это может также зависеть от версии. Использование подзапроса должно заставить его работать последовательно.

+0

Не могли бы вы объяснить «Cross Join», спасибо! –

+1

'CROSS JOIN' - это соединение без каких-либо условий. Он просто выполняет полный перекрестный продукт между двумя таблицами. В этом случае подзапрос возвращает только одну строку. – Barmar

+0

И что происходит во второй строке с '@ f',' @ c', '@ d'? –