2016-02-03 2 views
1

Я хочу получить данные из моей базы данных за последние 31 дней. Когда столбец «финализирован» равен NULL, я хочу получить данные из столбца «сегодня», но если столбец «финализирован» не равен NULL, я хочу получить данные из столбца «финализирован». Я всегда хочу получить последнюю введенную строку.Проблема с SELECT CASE

ТАБЛИЦА MyEarnings

id   INT(11) AI 
date  datetime 
today  decimal(4,2) NULL 
finalized decimal(4,2) NULL 

id date     today finalized 
----------------------------------------------- 
6  2016-02-04 04:52:00 0.39  NULL 
5  2016-02-03 12:34:00 NULL  19.74 
4  2016-02-03 12:33:00 15.96 NULL 
3  2016-02-03 12:32:00 12.32 NULL 
2  2016-02-02 15:16:00 NULL  9.16 
1  2016-02-02 14:29:00 2.20  NULL 

SQL

SELECT 
    date, 
    CASE 
     WHEN finalized=NULL 
      THEN today 
     WHEN finalized!=NULL 
      THEN finalized 
     END 
    AS earn 
FROM MyEarnings 
GROUP BY DATE_FORMAT(date, '%Y-%m-%d') 
ORDER BY date ASC 
LIMIT 0 , 31 

Это то, что я в конечном итоге с

date     earn 
--------------------------- 
2016-02-02 00:00:00 NULL 
2016-02-03 00:00:00 NULL 
2016-02-04 00:00:00 NULL 

Что я ищу, чтобы получить

date     earn 
---------------------------- 
2016-02-02 00:00:00 9.16 
2016-02-03 00:00:00 19.74 
2016-02-04 00:00:00 0.39 

EDIT

Я также хочу получить сводку за каждый месяц всех значений в «финализированном» столбце с максимальным «id» для каждого дня.

ответ

1

Вам нужна условная агрегация, но это немного сложно. Я думаю, что это делает то, что вы хотите:

SELECT DATE_FORMAT(date, '%Y-%m-%d'), 
     COALESCE(MAX(finalized), MAX(today)) as earn 
FROM MyEarnings 
GROUP BY DATE_FORMAT(date, '%Y-%m-%d') 
ORDER BY date ASC 
LIMIT 0 , 31; 

Это возвращает максимальное значение today. Возможно, вам понадобится последнее значение. Если да, то самый простой способ, вероятно, GROUP_CONCAT()/SUBSTRING_INDEX() метод:

SELECT DATE_FORMAT(date, '%Y-%m-%d'), 
     COALESCE(MAX(finalized), 
       SUBSTRING_INDEX(GROUP_CONCAT(today ORDER BY date DESC), ',', 1) + 0 
       ) as earn 
FROM MyEarnings 
GROUP BY DATE_FORMAT(date, '%Y-%m-%d') 
ORDER BY date ASC 
LIMIT 0 , 31; 

Это немного противный для преобразования чисел в строки и обратно для этой цели. Альтернативные методы требуют дополнительных объединений или использования переменных.

+0

Спасибо, но это не всегда MAX-значение, которое я хочу, так как когда мои доходы завершены, его можно опустить. Поэтому мне нужна строка с самым высоким «id». –

+0

Это именно то, что я хотел сделать! Спасибо! –

+0

Вопрос, будет ли ваш последний код дать мне MAX окончательное решение, если бы было более низкое значение в «финализированном», добавленном с более поздней датой? Я хочу, чтобы и «today'-column», и «finalized»-column дали мне значение с самым высоким ID. –

2

использование CASEWHEN так:

CASE 
     WHEN finalized IS NULL 
      THEN today 
     ELSE finalized 
     END 
AS earn 

Заменить запрос:

SELECT date, (CASE 
        WHEN finalized IS NULL THEN today 
        ELSE finalized 
       END;  
) AS earn 
FROM MyEarnings 
GROUP BY DATE_FORMAT(date, '%Y-%m-%d') 
ORDER BY date ASC LIMIT 0,31 
2

Вы не можете сравнить с нулевым =, вы должны использовать является недействительным и не равно нулю, как это:

SELECT 
date, 
CASE 
    WHEN finalized is null THEN today 
    ELSE finalized 
    END AS earn 
FROM MyEarnings 
GROUP BY DATE_FORMAT(date, '%Y-%m-%d') 
ORDER BY date ASC LIMIT 0 , 31 

Кроме того, если ваше первое условие - это когда его значение null, вам не нужно проверьте, будет ли его не null, ELSE будет достаточно, так как противоположность null не равна нулю.

0

Используя наибольший идентификатор, чтобы определить последнюю строку добавляется (минусы: растяжку традиционного использования ID):

SELECT DATE(me.date) date, 
     COALESCE(me.finalized,me.today) earn 
    FROM MyEarnings me 
    JOIN (
    SELECT MAX(id) max_id 
     FROM MyEarnings 
    GROUP BY DATE(date) 
    ORDER BY DATE(date) 
    LIMIT 31 
    ) o 
    ON o.max_id = me.id 

Использования наибольшей даты для определения последней строки добавлена ​​(минусов: возможные дубликаты):

SELECT DATE(me.date) date, 
     COALESCE(me.finalized,me.today) earn 
    FROM MyEarnings me 
    JOIN (
    SELECT MAX(date) max_date 
     FROM MyEarnings 
    GROUP BY DATE(date) 
    ORDER BY DATE(date) 
    LIMIT 31 
    ) o 
    ON o.max_date = me.date