Какова цель использования WHERE 1 = 1 в операторах SQL?

Возможные дубликаты:
Почему будет ли запрос sql иметь где 1 = 1
Зачем кому-то использовать WHERE 1 = 1 AND ‹conditions› в предложении SQL?

Я много раз видел это в различных примерах запросов, и это касается, вероятно, всех механизмов SQL.

Если есть запрос, в котором не определены условия, люди (и особенно ORM-фреймворки) часто добавляют условие «всегда верно» WHERE 1 = 1 или что-то в этом роде.

Так что вместо

SELECT id, name FROM users;

они используют

SELECT id, name FROM users WHERE 1 = 1;

Единственная возможная причина, о которой я мог подумать, если вы добавляете условия динамически, вам не нужно беспокоиться об удалении начального AND, но все же довольно часто это 1 = 1 условие удаляется, если в запросе есть фактическое условие.

Фактический пример из CakePHP (сгенерированный фреймворком):

(без условий)

SELECT `User`.`id`, `User`.`login`
FROM `users` AS `User` WHERE 1 = 1 
ORDER BY `User`.`id` ASC;

(с условием)

SELECT `User`.`id`, `User`.`login`
FROM `users` AS `User` 
WHERE `User`.`login` = '[email protected]'
LIMIT 1;

Есть ли причина для добавления этого дополнительного условия?


person RaYell    schedule 12.08.2009    source источник
comment
Обман stackoverflow.com/questions/517107/ среди других   -  person    schedule 12.08.2009


Ответы (6)


Да, обычно это потому, что оно начинается как «где 1 = 0», чтобы заставить инструкцию не работать.

Это более наивный способ завернуть его в транзакцию и не фиксировать ее в конце, чтобы проверить свой запрос. (Это предпочтительный метод).

person Noon Silk    schedule 12.08.2009
comment
Ответов может быть несколько; и в этом случае OP был специфическим, что он не только для создания динамических запросов (и, честно говоря, если вы создаете динамические запросы в наши дни ORM, внимательно посмотрите на себя). - person Noon Silk; 12.08.2009

Это также обычная практика, когда люди создают запрос sql программно, просто проще начать с 'where 1 = 1', а затем добавить 'и customer.id =: custId' в зависимости от идентификатора клиента предоставлен. Таким образом, вы всегда можете добавить следующую часть запроса, начинающуюся с 'и ...'.

person HeDinges    schedule 12.08.2009
comment
-1 Это повторение вопроса, в котором говорится, что вам не нужно беспокоиться об удалении начального AND - person Andomar; 12.08.2009

1 = 1 всегда игнорируется всеми rdbms. Нет никакого компромисса при выполнении запроса с WHERE 1 = 1.

При построении динамических условий WHERE, таких как ORM-фреймворки или другие, очень часто, проще добавить реальные условия where, потому что вы избегаете проверки добавления AND к текущему условию.

stmt += "WHERE 1=1";
if (v != null) {
   stmt += (" AND col = " + v.ToString());
}

Вот как это выглядит без 1 = 1.

var firstCondition = true;
...
if (v != null) {
   if (!firstCondition) {
      stmt += " AND ";
   }
   else {
       stmt += " WHERE ";
       firstCondition = false;
   }
   stmt += "col = " + v.ToString());
}
person Christian13467    schedule 12.08.2009
comment
На самом деле я обычно делаю что-то вроде: cmd = select ...; sep = где; foreach (cond) {cmd + = sep + cond; sep = и; } - person paxdiablo; 12.08.2009
comment
Что выглядит немного чище. - person paxdiablo; 12.08.2009
comment
Хорошая идея! Сохраняю это для дальнейшего программирования. - person Christian13467; 16.08.2009
comment
хотя это прекрасно объясняет, почему мои коллеги делают это, я все время задаюсь вопросом, хорош ли этот стиль кодирования или нет - person Dheeraj; 03.03.2021

Люди используют его, потому что они по своей природе ленивы при построении динамических SQL-запросов. Если вы начинаете с "where 1 = 1", тогда все ваши лишние предложения просто начинаются с "and", и вам не нужно разбираться.

Не то чтобы нет ничего плохого в том, чтобы быть ленивым по своей природе. Я видел двусвязные списки, где «пустой» список состоит из двух контрольных узлов, и вы начинаете обработку с first->next до last->prev включительно.

Это фактически удалило весь специальный код обработки для удаления узлов first и last. В этой настройке каждый узел был средним, поскольку вы не могли удалить first или last. Два узла были потрачены впустую, но код был проще и (хоть немного) быстрее.

Единственное другое место, где я когда-либо видел конструкцию «1 = 1», - это BIRT. В отчетах часто используются позиционные параметры и они изменяются с помощью Javascript, чтобы разрешить все значения. Итак, запрос:

select * from tbl where col = ?

когда пользователь выбирает "*" для параметра, используемого для col, изменяется на чтение:

select * from tbl where ((col = ?) or (1 = 1))

Это позволяет использовать новый запрос без возни с деталями позиционного параметра. Еще есть ровно один такой параметр. Любая достойная СУБД (например, DB2 / z) оптимизирует этот запрос, чтобы полностью удалить предложение перед попыткой построения плана выполнения, так что компромисса нет.

person paxdiablo    schedule 12.08.2009
comment
Спасибо чувак! Это был наиболее правдоподобный ответ! - person Thiago Augustus Oliveira; 30.09.2015

Как ты сказал:

если вы добавляете условия динамически, вам не нужно беспокоиться об удалении начального значения, и это может быть единственная причина, вы правы.

person Wael Dalloul    schedule 12.08.2009

Использование 1 = 1 на самом деле не очень хорошая идея, поскольку это может привести к полному сканированию таблицы само по себе.

См. Это -> T-SQL 1 = 1 снижение производительности

person Bhaskar    schedule 12.08.2009
comment
Только на самой хреновой из СУБД. - person paxdiablo; 12.08.2009
comment
Все ответы в вопросе, на который вы указали 1 = 1, не имеют никакого значения. - person Ryan; 12.08.2009