有没有更好的方法来进行这个查询?

Posted

技术标签:

【中文标题】有没有更好的方法来进行这个查询?【英文标题】:Is there a better way to make this query? 【发布时间】:2014-04-10 19:21:14 【问题描述】:

我想知道是否有更好的方法来编写以下查询:

IF EXISTS (SELECT * 
           FROM   master_list 
           WHERE  code = 'r_params') 
  BEGIN 
      UPDATE master_list 
      SET    code = 'w_params' 
      WHERE  code = 'r_params' 
             AND NOT name_1 = 'pH' 
             AND NOT name_2 = 'Flow' 
             AND NOT name_3 = 'Temperature' 

      SELECT * 
      FROM   r_master_list 
      WHERE  code = 'r_params' 

      SELECT * 
      FROM   r_master_list 
      WHERE  code = 'w_params' 
  END

谢谢

【问题讨论】:

使用&lt;&gt; 而不是not = 或使用!=,意思相同 您的代码的实际问题是什么?它不运行吗?请指定一个具体问题,因为在 Stack Overflow 上要求“更好”解决方案的问题不在主题范围内。 Should I use != or <> for not equal in TSQL?的可能重复 必须绝对返回两个结果集吗?为什么不是一个代码是 r_params 或 w_params 的? 【参考方案1】:
if exists (select * from MASTER_LIST where Code = 'r_params')
begin
    update MASTER_LIST 
      set Code = 'w_params' 
      where Code = 'r_params' 
      AND  Name_1 <> 'pH' 
      AND  Name_2 <> 'Flow' 
      AND  Name_3 <> 'Temperature'

 select * from R_MASTER_LIST  WHERE Code = 'r_params'

 select * from R_MASTER_LIST WHERE Code = 'w_params'
end

【讨论】:

【参考方案2】:

SELECT 1 可能更快

IF EXISTS (SELECT 1 
           FROM   master_list 
           WHERE  code = 'r_params') 
  BEGIN 
      UPDATE master_list 
      SET    code = 'w_params' 
      WHERE  code = 'r_params' 
             AND name_1 <> 'pH' 
             AND name_2 <> 'Flow' 
             AND name_3 <> 'Temperature' 

      SELECT * 
      FROM   r_master_list 
      WHERE  code = 'r_params' 

      SELECT * 
      FROM   r_master_list 
      WHERE  code = 'w_params' 
  END

【讨论】:

你确定吗?我原以为EXISTS 函数足够聪明,不会返回任何字段... @Crono 我相信这个问题实际上可能存在一些争论:blog.sqlauthority.com/2008/02/26/… 似乎有很多人声称这是正确的,但也有很多人说相反。无论哪种方式,我确实看到了这种方法的好处:它允许您在代码库中搜索以SELECT * 开头的查询,而无需到达嵌套在EXISTS 函数中的此类查询。这有点长远,但仍然很有价值。 +1 我不确定它是否更快,但我认为它使声明的意图更加清晰【参考方案3】:

抛开客户期望接收数据的形式不谈,更好的方法是将两个结果集合并为一个

IF EXISTS (SELECT * 
    FROM   master_list 
    WHERE  code = 'r_params') 
BEGIN 
    UPDATE master_list 
    SET    code = 'w_params' 
    WHERE  code = 'r_params' 
        AND name_1 <> 'pH' 
        AND name_2 <> 'Flow' 
        AND name_3 <> 'Temperature' 

    SELECT * 
    FROM   r_master_list 
    WHERE  code IN ('r_params', 'w_params')
END

这样您就可以对r_master_list 进行一次查询,而不是两次。客户端将收到完全相同的数据;只有他有责任将其拆分为不同的结果集,如果他需要的话。性能和效率方面,这应该是首选的解决方案。

更新:

正如 Drew 建议的那样,您可能还希望像这样创建“EXISTS”函数子查询:

IF EXISTS (SELECT 1 
FROM   master_list 
    WHERE  code = 'r_params') 

关于这是否更有效存在相当大的争论。德鲁似乎相信它是;我一个人说不出来。但!这种方法还有一个 Drew 没有提到的优势:如果您想使用 * 查找整个代码库中的字段的 SELECT 查询,您会发现所有 EXISTS 函数子查询都使用SELECT 1 模式,这样您就不会不必要地接触到那些人。可能不多,但我仍然认为值得一提。

【讨论】:

【参考方案4】:

这是多余的 更新的条件之一是 WHERE code = 'r_params'

IF EXISTS (SELECT * 
           FROM   master_list 
           WHERE  code = 'r_params') 

这就够了

  UPDATE master_list 
  SET    code = 'w_params' 
  WHERE  code = 'r_params' 
         AND NOT name_1 = 'pH' 
         AND NOT name_2 = 'Flow' 
         AND NOT name_3 = 'Temperature' 

  SELECT * 
  FROM   r_master_list 
  WHERE  code = 'r_params' 

  SELECT * 
  FROM   r_master_list 
  WHERE  code = 'w_params' 

唯一的区别是即使没有'r_params',你也会得到最后一个选择

最后两个可以合并

SELECT * 
  FROM r_master_list 
 WHERE code in  ('r_params','w_params') 
 order by code

【讨论】:

以上是关于有没有更好的方法来进行这个查询?的主要内容,如果未能解决你的问题,请参考以下文章

子选择或连接?有没有更好的方法来编写这个 mysql 查询?

有没有更好的方法来排序这个查询?

有没有比多个子查询更好的方法来获得这个,也许有更多的连接?

有没有更有效的方法来执行这个嵌套的 SQL 查询?

有没有更好的方法来做这些 mysql 查询?

MySQL 查询:有没有更好的方法来根据birth_date 日期字段获取 X 岁或以上的用户