从表tablename中选择所有行,其中条件为1。

130
我很好奇,这三个查询有什么不同:
1. SELECT * FROM `tablename` 2. SELECT * FROM `tablename` WHERE 1 3. SELECT * FROM `tablename` WHERE 1=1

9
标签中是否有“过于狭窄”的标记?因为这适用于许多SQL方言,如果不是全部的话。我在MSSQL和Oracle中也经常看到它。顺便问一下,这些撇号是什么?难道不是用反引号 ` 来引用mysql对象名称吗? - Cee McSharpface
3
你可以编辑标签,@dlatikay。 - Braiam
2
嗯,为什么不直接使用 ... WHERE TRUE 呢?我知道(在大多数 SQL 中,包括 MySQL)TRUE 只是一个代表 1 的花哨宏 - 但是,对于读者来说这不是更明显一些吗? - user719662
2
在大多数 SQL 方言中,2 是无效的。 - edc65
显示剩余4条评论
10个回答

177

在MySQL中,2和3在功能上是相同的,1也是相同的。

where 1 不是标准写法,因此,正如其他人指出的那样,在其他方言中不起作用。

人们添加where 1where 1 = 1,这样可以通过添加/注释一些"and..."组件来轻松地向查询添加或删除where条件。

例如:

SELECT * FROM `tablename` WHERE 1=1
--AND Column1 = 'Value1'
AND Column2 = 'Value2'

11
当您以编程方式构建一个查询字符串以便稍后执行时,如果您添加了WHERE 1=1,则无需担心您正在尝试添加到字符串中的条件是第一个条件(因此需要在前面添加WHERE)还是不是。请注意,这样做不会改变原来的意思。 - Vicente Olivert Riera
45
编程已有6年,从未想过做这个 - 谢谢! - SimonGates
6
如果您要将两个或多个SELECT语句合并,那么需要使用ORDER BY 1语法(而不是列名)。请注意,这不会改变原始意思。 - Mark Stewart
5
我已经编程六年了,从未考虑过做其他事情 lol. - WernerCD
4
我认为更明智的做法是在某种列表中建立过滤条件列表,然后使用“AND”作为分隔符将它们连接成字符串。 - Zev Spitz
显示剩余7条评论

76

正如你所知,它们三个都可以产生相同的结果。(在布尔上下文中,MySQL将整数“1”视为true - 实际上,任何不是“0”的数字都被视为true)。

MySQL优化器明确地记录了在WHERE子句中删除常量条件:

  • 常量条件删除......:

    (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6

因此,它们都将编译成完全相同的代码。

它们功能上相等,应该具有相同的性能特征。

话虽如此,第一个和第三个是标准 SQL。第二个将在许多数据库中导致某种布尔表达式错误。因此,我建议您避免使用它(我不确定它是否在MySQL的严格SQL模式下工作)。

通常在构建动态WHERE子句时使用第三个。这使得可以添加其他条件作为AND <condition>而不必担心残留的AND


6
这是一个更好的答案,它涵盖了另一篇答案的所有内容,但重要的是指出第二个答案不符合 ANSI 标准。 - underscore_d

16

如果您询问性能和结果的差异,那么并没有差异,2和3是相同的WHERE TRUE,它们将产生与第一个相同的结果。

1 - SELECT * FROM table_name

table_name表中获取所有数据(没有过滤器)的结果。

2 - SELECT * FROM table_name WHERE 1

1将被评估为TRUE,因此-没有过滤器-每条记录都将被返回。

3 - SELECT * FROM table_name where 1=1

和上一个例子一样,1=1是一个TRUE表达式,因此没有过滤器,每条记录都将被选择。


14

所有的东西都是一样的,但是2和3被用来方便地处理像AND/OR这样的条件,例如:

SELECT * FROM `tablename` WHERE 1=1 AND (columnname1 = 'Value' OR columnname2 = 'Value')

8

在第1种情况下,MySQL不需要评估任何WHERE条件。

在第2和第3种情况下,where条件是静态的,不基于行的值。它将使用布尔逻辑进行评估,并始终为真。

从功能上讲,没有区别。您应该选择第1种情况以提高代码清晰度。


7
所有的内容都是相同的,但是2和3用于创建动态查询的AND/OR条件。
sqlquery ="  SELECT * FROM `tablename` where 1 =1 "

我们使用2和3格式来创建动态查询,因此我们已经知道“where”关键字被添加,并且我们继续添加更多的过滤器。例如:

sqlquery  = sqlquery + "and columna =a"
"AND columna =a " then

如果我们有新的过滤器,只需要加入"AND coulmnb =b "等语句即可。

无需检查SQL查询中WHERE关键字是否已放置在第一个或初始查询中。

SELECT * FROM `tablename` WHERE 1=1 AND (columnname1 = 'Value' OR columnname2 = 'Value')

否则,我们可以编写sqlquery =“SELECT * FROM tablename” 然后,如果在 sqlquery 中没有“where”子句,则
sqlquery  = sqlquery + "where columna =a"

否则
sqlquery  = sqlquery + "and columna =a"

4个前导空格表示代码块。请[编辑]您的答案以正确格式化它,并查看编辑帮助获取整个Markdown格式化圣经。 - Mathieu Guindon

4
他们都输出相同的答案。然而,2和3的写法主要是为了控制“Where”语句,以便稍后更轻松地添加或删除它。
我认为第一种和第三种写法是正确的。如果你需要一个where语句,你可以像第三种那样写,否则第一种就足够了。

3

在MS SQL中,1和3是相同的,但选项2将无法工作,因为在MS SQL中,WHERE用于比较一些值。例如:

  1. Select * from 'myTable where ID = 3(有效)
  2. Select * from 'myTable where 1 = 1与Select * from' myTable where 2 = 2与Select * from' myTable where 3 = 3相同,你懂的(有效),与Select * From' myTable'相同

2
  1. SELECT * FROM table_name:它将为您提供表中所有记录,而不运行任何where语句。
  2. SELECT * FROM table_name WHERE 1:这个where条件总是成立,它经常被黑客用来进入任何系统。如果你听说过SQL注入,那么2和3就是黑客强制构建的场景,以获取表中的所有记录。
  3. SELECT * FROM table_name where 1=1:这将为您提供表中的所有记录,但它将比较where语句并继续前进,它基本上是添加或删除更多语句之后添加的。

1

结果 - 给出指定表中的所有记录,而不是所有三个查询的表名

SELECT * FROM tablename WHERE 1 - 检查这个答案

SELECT * FROM tablename WHERE 1=1 - 检查这个答案

有关WHERE子句优化的更多信息,请查看以下内容:MYSQL, SQLite, SQL


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接