2016-01-11 4 views
0

В настоящее время у меня есть два запроса, один из которых отображает все данные (независимо от времени), другой, который считает временной интервал. Я пытаюсь сконденсировать их вместе и задавался вопросом, имеет ли mysql что-то для dateTimes, которое действует как переменная allTime, то есть при подключении к ней:
select count(*) from table where (color = "red") and (dateMade between "allTime" and "allTime");
отображает количество строк, в которых цвет красного цвета, для всех строк в таблице. Решение, о котором я думал, состояло в том, чтобы просто использовать минимальную дату 0000-01-01 00:00:00 и некоторую большую дату окончания конца, но если уже существует что-то, что можно было бы решить, я подумал, что могу использовать это.

Выберите данные из всех дат.

EDIT: Это будет использоваться не только для примера, описанного выше, но и для большинства из них гораздо более продолжительный и сложный. Цель состоит в том, чтобы объединить это с узлом, чтобы упростить функции и не учитывать частный случай всех данных, а просто использовать запрос временных рамок и возвращать все данные на основе оценок, приведенных в качестве аргументов.

+0

Я думаю, вы можете просто удалить предложение date, чтобы получить ваши записи allTime, поэтому ваш запрос будет выглядеть как 'select count (*) из таблицы, где color =" red "' – vmachan

+0

Да, я могу это сделать, и я делая это в настоящее время для моего всего запроса данных. Я пытаюсь сделать два запроса в одном, но, так как мой запрос на временной интервал требует дат, мне нужно указать какие-то даты для всего запроса времени для их объединения. Извините, если я был неясен в этом – yanman1234

ответ

1

Заполните переменные @from и/или @to с NULL, если вы не хотите, чтобы ограничить данные. Используйте IFNULL, чтобы проверить, должно ли применяться ограничение или нет.

select count(*) 
from table 
where color = @color 
and datemade between ifnull(@from, datemade) and ifnull(@to, datemade); 
+0

Из того, что я читал, IFNULL кажется неэффективным в больших пулах данных, согласны ли вы с этим или устарели? Кроме того, ваше решение действительно работает, но как вводить имя столбца, чтобы это работало? Я просто смущен тем, как sql действительно читает, что – yanman1234

+0

IFNULL здесь не проблема; он применяется только один раз для каждой переменной (не для записи). Если @from имеет значение null, критерии становятся «и datemade между datemade ...». То же самое для @to. Таким образом, СУБД сразу видит, нужно ли сравнивать дату и время со значением или нет. ('isnull (datemade, something)', с другой стороны, будет применяться на запись, поэтому это может замедлить такой запрос, но мы этого не делаем.) –

+0

Здесь вы не вводите никаких имен столбцов.У вас есть три переменные: один для цвета, один для нижнего предела и один для верхнего. Цвет является обязательным, ограничения по дате отсутствуют; вы можете установить их равными нулю, если вы не хотите их использовать. Таким образом, у вас есть запрос, который может использоваться с верхним и нижним лимитом даты, причем только один из двух или даже ни один из них. Он остается одним и тем же запросом, только содержимое переменных отличается. –

0

Не пропускайте данные дважды, если только вам это не нужно, вы можете использовать «условную агрегацию», например,

select 
    count(*) all_count 
    , count(case when dateMade between @start and @end then id end) period_count 
from table 
where (color = "red") 

Чтобы получить «все время», вы просто не фильтруете по диапазону дат в предложении where.

Обратите внимание, что функция COUNT() прирастает для любого непустого значения, которое она встречает, поэтому для выражения case он должен возвращать столбец, который всегда будет присутствовать в строке, такой как первичный ключ.

Альтернативой является использование SUM() вместо того, чтобы, как этот

select 
    count(*) all_count 
    , sum(case when dateMade between @start and @end then 1 else 0 end) period_count 
from table 
where (color = "red") 
+0

. Итак, в основном вы предлагаете объединить оба запроса в один оператор с двумя переменными и использовать соответствующую переменную для любой задачи, для которой я использую этот оператор? – yanman1234

+0

Да, и было бы более эффективно передавать данные только один раз. –

1

В тех случаях, когда вам не нужен диапазон дат можно сделать частью пункта where истинно-иш Noop:

select ... 
from tablename 
where date_created between $start and $end or $start = $end 

Затем, если вам нужен неограниченный запрос, просто передать то же $ start и $ end.

Смежные вопросы