Why use WHERE 1 = 1 in an SQL query?

Asked

Viewed 17,606 times

63

During the maintenance of a legacy system I found the following Procedure:

DECLARE @sql AS varchar(MAX);
DECLARE @param as varchar(50);

SET @sql = 'SELECT * FROM Destinatario where 1 = 1';

IF(@param IS NOT NULL)
    SET @sql = (@sql + ' AND Nome = ''' + @param + '''');
EXEC(@sql)

The first thing that caught my attention was the condition Where 1 = 1

  • Why the programmer who wrote this project used this condition?
  • 4

    Related: http://desciclopedia.org/wiki/Gambi_Design_Patterns#AND_0.3D0

  • In some conditions I use confessed.

  • Be careful with this technique because when you use it.. if you see nothing in others ands the database will fetch all the existing records in the table. That is if you have 10million records and have no other filters it will fetch everything..

2 answers

86


This condition in principle does not appear to be right, because removing it gives in the same.

However, when Where conditions are generated dynamically, and the programmer adds them with AND inside ifs, because these depend on other factors of the program that generates SQL, it is clear its intention:

If there is no additional condition, the query remains so ...

SELECT * FROM Destinatario where 1 = 1

... but in the case, if the condition is true right after your example, it can stay:

SELECT * FROM Destinatario where 1 = 1 AND Nome = "Roberto"

Note that if there was no WHERE 1=1, it would stay that way, and it wouldn’t work:

SELECT * FROM Destinatario AND Nome = "Roberto" 
  -- temos um erro aqui --^

For one condition AND only, the author could have put the WHERE within the condition, but if there are various conditions, the WHERE 1=1 would allow several separate conditions, mounted by ifs different:

SELECT * FROM Destinatario where 1 = 1
SELECT * FROM Destinatario where 1 = 1 AND Nome = "Roberto"
SELECT * FROM Destinatario where 1 = 1 AND Cidade = "Santos"
SELECT * FROM Destinatario where 1 = 1 AND Nome = "Roberto" AND Cidade = "Santos"

Thus the AND Nome could be in a if and the AND Cidade in another, and all would function independently of having to know if there is already a if previous in the code generating the SQL.

As mentioned by @bfavaretto, Cakephp, for example, uses this technique.

In particular, I find it better to use cleaner ways than how it was used, such as concatenating with AND only when it comes to the second condition onwards, but each has its own criteria, and at each moment a particular technique may be better than another.

Leaving this specific example of use, it may even happen that someone uses a WHERE "neutral" when you want to test some condition during code development, eliminating the original condition (equivalent to putting WHERE true, which would also serve for the initial explanation), but this is already another story.

In our specific case, the IF this row confirms the initial hypothesis of the optional parameter with AND:

IF(@param IS NOT NULL) -- <== Aqui 
    SET @sql = (@sql + ' AND Nome = ''' + @param + '''');
  • That kind of joker was used a lot in the old days? You can show me an alternative to this technique?

  • 1

    To tell you the truth I only saw it now, to answer your question, I wouldn’t do it this way. I usually leave without Where anyway. When there are several Where in a loop, I simply start with a Where="WHERE", and in the loop I put Where = Where + Glue + conditio for example. Glue starts empty, but it turns "AND" inside the first loop loop, ie, will only be applied from 2nd onwards.

  • 4

    @Laerte Cakephp uses this 1=1 to facilitate the generation of queries. But as Bacco rightly said, it would be possible to avoid.

  • Great! I was with this doubt, because it is very common in Mysql to use WHERE 1, without the same.

  • Creating a string from items in a list with a fixed separator is a very old problem and almost all languages have a function to solve it (usually called join). The ideal is to use this instead of reinventing the wheel.

  • @Gabriel O Join seve well to make the list... But it does not serve to resolve what is in the question, which is the word Where. The problem here is not the separator, but the fact that if you have no condition, there is no empty WHERE.

  • @Bacco I know. What I said was not an attempt to answer the question, so much that I did not post as an answer, but as a comment. It was more a warning to the navigators who insist on writing a loop in the hand juggling with numerical indexes to recreate the implementation of a join.

  • @Gabriel ok... I just mentioned how you got a little "lost" in the comments without an introduction (like: "complementing, creating a ..." ) I thought maybe you had attempted the wrong detail and I decided to extend the subject.

  • @Bacco My main motivation was the excerpt: "I find it better to use cleaner ways than how it was used, such as concatenating with AND only when it comes to the second condition on" that will probably encourage people to make the old loop that I mentioned before.

  • You know Join is a loop right? The fact of being in a native function and having been written by the author of the language and not by the application does not change this fact. And there are situations that you want AND, OR and more than one kind of connection, which Join doesn’t solve. Now, that in languages that have multiple concatenation with separator (Join in PHP, concat_ws in Mysql, actually simplifies the typing of code).

Show 5 more comments

8

There are other interesting points to be raised for this solution with WHERE 1 = 1.

Code clarity

One advantage of this technique is that the code ends up staying cleaner, so there need not be control of the presence of the WHERE vs AND/OR, keeping independent the order of the filters that will enter the query and if any filter will enter the query.

Impact on performance

There is a recurring doubt regarding the impact of performance in the database of the presence of WHERE 1 = 1, whether there are other filters or not. What can I say to most databases does not suffer any performance impact when using this technique.

Doing an impact analysis on the Sql Server execution plan, with 10,000 records in a table, no change was noticed between the plan containing WHERE 1 = 1 and the plan without the same.

Other option

Some databases also support WHERE 1, although this is not the recommended option because it is not part of the ANSI standard.

  • 1

    What was the reason for the negative vote? I tried to add some more information besides the accepted answer: cleaner code, be optional when there is a mandatory filter and respond to a common performance query. The Bounty was generated so that a new response meets other concerns and I understand that’s what I did.

  • 2

    I will not deny because the answer is not wrong, and I see no reason to deny, of course I think it is important to add new or relevant information to an old answer when necessary, but in this case I saw nothing that added... If it were me, instead of creating a new answer, I would edit the Stock and add this information where it fits

  • 1

    Interesting would be who negatived explain the reason of the negative, thus showing their point of view

Browser other questions tagged

You are not signed in. Login or sign up in order to post.