2015-08-17 3 views
0

У меня есть таблица «Задачи», который выглядит следующим образом: enter image description hereСравните даты той же колонке MySql Laravel

Мне нужно вычислить дату начала смещения для каждой записи; Мне нужно рассчитать, сколько дней после минимальной/младшей даты начала даты начала каждой записи.

Я делаю это в Laravel 4. Таблица mySQL. Я бы предпочел запрос Laravel, но я, вероятно, также могу включить raw mySQL.

Мой запрос (он выбирает некоторые другие вещи, тоже) не работает

$tasks = DB::table('tasks')->select(array(DB::raw("TIMESTAMPDIFF(DAY, MIN(start), start) AS offset"), DB::raw("TIMESTAMPDIFF(DAY, start, end) AS length"), 'user_id', 'name', 'desc','start','end','finished'))->where('temp_id', $id)->orderBy('start')->get(); 

«MIN (начало)» для себя сравнить, как представляется, проблема. Как рассчитать, сколько дней после даты начала минимальной даты начала каждой записи?

+0

Я могу быть полностью вне базы здесь, но не 'MIN()' агрегатная функция, чтобы найти наименьшее значение в группе записей? Если это так, я не думаю, что это имело бы смысл при использовании в поле DATETIME в одной строке. –

+0

Я не могу говорить ни о чем, Ларавеле, но это обычное @TimLewis. См. Этот ответ [здесь] (http://stackoverflow.com/a/32030445/1816093), который я написал, например, но используя 'max' not' min' – Drew

+0

@Drew Lovervel-builder - это оболочка для базового SQL синтаксис, и глядя на ваш ответ, дает некоторое представление. Я напишу здесь быстрый ответ. –

ответ

0

Я вижу два возможных решения для решения неправильного использования MIN(start) в неагрегированном результирующем наборе.

Вариант один: Сохранить переменную для минимальной даты и использовать его в запросе:

$min_date = DB::table("tasks")->selectRaw("id, MIN(start) AS min")->groupBy("id")->first(); 
echo $min_date->min; // 2015-08-15 00:00:00, assuming my syntax was correct. 

$tasks = DB::table('tasks') 
->select(array(DB::raw("TIMESTAMPDIFF(DAY, ".$min_date->min.", start) AS offset"), DB::raw("TIMESTAMPDIFF(DAY, start, end) AS length"), 'user_id', 'name', 'desc','start','end','finished')) 
->where('temp_id', $id) 
->orderBy('start') 
->get(); 

Вариант два: использовать подзапрос в избранных:

$tasks = DB::table('tasks') 
->select(array(DB::raw("TIMESTAMPDIFF(DAY, (SELECT MIN(start) FROM tasks), start) AS offset"), DB::raw("TIMESTAMPDIFF(DAY, start, end) AS length"), 'user_id', 'name', 'desc','start','end','finished')) 
->where('temp_id', $id) 
->orderBy('start') 
->get(); 

Обратите внимание на MIN() использования: Он может использоваться без агрегирования результатов, но возвращает только одну строку, если она не используется в подзапросе.

Примеры:

SELECT start FROM tasks; /*6 Rows*/ 
SELECT MIN(start) FROM tasks; /*1 Row*/ 
SELECT MIN(start), start FROM tasks; /*1 Row*/ 
SELECT (SELECT (MIN(start) FROM tasks) AS min_start, start FROM tasks; /*6 Rows*/ 

Последний пример будет возвращать результаты из каждой строки наряду с минимальным start найденного в tasks. Надеюсь, это помогло очистить вашу проблему. Любой вариант 1 или вариант 2 должен помочь, но оставьте комментарий, в котором вам нужна помощь с чем-либо еще.

+0

Я думаю, что это то, что для себя или для подзапросов. Я сделал вариант №1 с двумя запросами, но мне пришлось изменить котировки вокруг $ min_date-> low DB :: raw ("TIMESTAMPDIFF (DAY, '". $ Low_date-> start. "', Start) AS offset «), –