【问题标题】:select ... where id = any value. is it possible?选择 ... 其中 id = 任何值。可能吗?
【发布时间】:2011-02-22 03:07:03
【问题描述】:

请看这张表

table
|id| |name| |order|

我必须得到行,name = somethingorder = somevalue

所以我写了

select `id` from `table` where `name` = 'something' and `order` = 'somevalue'

但取决于 php 逻辑,有时我需要获取所有行,其中 name = something,独立于 order 值。我不想更改查询结构,因为实际上有很多字段,并且可能的查询数会变得非常大。所以我想保存查询的结构,当我需要按名称选择时,我想写这样的东西:

select `id` from `table` where `name` = 'something' and `order` = any value 

有可能吗?

谢谢

【问题讨论】:

  • 我会改变您构建查询的方式...

标签: php mysql phpmyadmin


【解决方案1】:

嗯,这是一种 hack,但如果你真的需要这样做,它会像这样工作:

select `id` from `table` where `name` = 'something' and `order` = `order`

那么你只是在说“只要顺序与自身相同”,所以它总是正确的。

【讨论】:

  • 我会考虑改变结构,因为引用字段的语法与引用字符串的语法不同。
  • 这不是正确的做法。 php代码需要调整。
【解决方案2】:

不,这是不可能的。您需要更改结构(可选为 LIKE,以便您可以使用 '%',但这非常难看)。

但是,您无需编写不同的查询来处理所有可能的组合。您可以简单地动态创建查询:

//create base query
$query = "select `id` from `table` where `name` = 'something' ";

//add order if we need it
if ($use_order)
  $query .= "and `order` = 'somevalue' ";

//repeat for any other optional part

请注意,您当然仍应采取适当的措施来避免 SQL 注入和其他安全问题 - 为了简单起见,我没有将其包含在此处。

【讨论】:

  • 什么是SQL注入?也许您谈论 mysql_real_escape_string() 和此类功能?我不明白“SQL注入”的含义
  • @Syom:SQL 注入是一种提供数据的行为,它会影响查询的结构,导致它做一些不应该做的事情。 mysql(i)_real_escape_string 确实是大多数人用来防止这种情况的方法(尽管严格来说参数化查询是一种更好的方法,但这是一个不同的话题)。如果您想了解更多信息,SO 上和 Google 上都有很多很好的资源。我想说的是,你仍然需要记住在动态构建时做这种事情。
【解决方案3】:

如果你使用绑定参数,那是不可能的。

如果您只是替换值,您可以执行以下操作:

select `id` from `table` where `name` = 'something' and `order` = `order`

【讨论】:

    【解决方案4】:

    我认为您别无选择...一旦您进行选择,您就无法“取消过滤”并获得更多行。

    您应该只使用两个查询——要么是两个独立的查询,要么是一个将名称选择到临时表中,然后(可选)一个进一步选择 order 属性。

    【讨论】:

      【解决方案5】:

      就像上面乍得说的,只需将列设置为等于它自己。但要小心,在某些平台/安装配置上,NULL != NULL:

      select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'')
      

      【讨论】:

      • NULL != NULL 实际上是 SQL 标准中定义的预期行为。
      【解决方案6】:

      这是数据库查询的一个常见主题 - 您需要一个变量查询,具体取决于您希望对其查询的数据应用多少过滤。您可以在整个代码中将查询作为字符串重复,但这是不好的做法,因为它不必要地增加了代码的复杂性。如果您出于某种原因需要更改查询,并且因此必须在多个位置进行更改,则可能会发生错误。

      更好的解决方案是创建一个为您执行构建查询的函数:

      function buildMyQuery($name, $order = null) {
          $sql = "SELECT `id` FROM `table` WHERE `name`='$name'";
      
          if ($order != null) {
              $sql .= " AND `order`='$order'";
          }
      
          return $sql;
      }
      

      然后您可以只使用“名称”字段来运行它:

      $query = buildMyQuery("somename");
      

      或者使用这两个字段:

      $query = buildMyQuery("somename", "someorder");
      

      正如上面有人提到的,这段代码是故意简化的,并且不包含通过 $name 或 $order 传入的可能危险数据的意外情况。您需要先在函数的开头使用 mysql_real_escape_string 或类似的东西来清理数据,然后再使用任何一条数据。

      正如 Byron 所说,动态查询生成已成为现实,所以我现在会习惯它,而不是使用 hack-ish 变通办法。

      【讨论】:

        【解决方案7】:

        经过反思,我有一个更好的答案。我的同事向我展示了一种可以做到这一点的方法。

        我的例子...

        Select rentals.* From rentals Where ((? = '') OR (user_id = ?))
        

        变量必须相同。

        例如,如果它们都是 5,则对于用户 id 为 5 的行,第一个布尔值为 false,但第二个布尔值为 true。

        如果您需要“all”,设置为空字符串将导致所有行都被视为满足 where 子句条件。

        【讨论】:

          【解决方案8】:

          你不能在这里使用not null 查询吗?

          select `id` from `table` where `name` = 'something' and `order` is not null;
          

          【讨论】:

            【解决方案9】:
            $sql = "SELECT * FROM auctions WHERE id = id ";
            
            if ($category !== "ANY") { 
            $sql .= "AND category = $category "; }
            
            if ($subcategory !== "ANY") { 
            $sql .= "AND subcategory = $subcategory "; }
            
            if ($country !== "ANY") { 
            $sql .= "AND country = $country "; }
            
            
            
            $sql .=  "ORDER BY $order $sort LIMIT $limit OFFSET $offset";
            

            【讨论】:

            • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。
            【解决方案10】:

            你应该可以这样做:

            select `id` from `table` where `name` <>'' and `order` <>''
            

            这将选择值不等于空白的任何地方。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-01-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-10
              • 1970-01-01
              相关资源
              最近更新 更多