代码之家  ›  专栏  ›  技术社区  ›  Clayton

我可以根据结果的数量将我的MySQL查询重构为一个查询吗?

  •  1
  • Clayton  · 技术社区  · 16 年前

    我有一张桌子 y 有两列 a b

    参赛作品有:

    a   b
    
    1   2
    
    1   3
    
    1   4
    
    0   5
    
    0   2
    
    0   4
    

    如果我搜索列,我想得到2,3,4 对于1和5、2、4,如果我搜索列 .

    因此,如果我搜索a中的某个内容,(1)我会得到这些行,如果给定值没有条目a,请给出“默认值”。( =“0”

    以下是我如何知道如何做到这一点:

    $r = mysql_query('SELECT `b` FROM `y` WHERE `a` = \'1\';');
    //This gives desired results, 3 rows
    
    $r = mysql_query('SELECT `b` FROM `y` WHERE `a` = \'2\';');
    //This does not give desired results yet.
    //Get the number of rows, and then get the 'defaults'
    if(mysql_num_rows($r) === 0) $r = mysql_query('SELECT `b` FROM `y` WHERE `a` = 0;');
    

    所以,既然已经充分解释了,那么如何在一个查询中做到这一点,以及性能问题呢?

    最常用的部分是第三个查询,因为 如果你偏离了默认值。

    6 回复  |  直到 10 年前
        1
  •  2
  •   Jonathan    16 年前

    我想我有:

    SELECT b FROM y where a=if(@value IN (select a from y group by a),@value,0);
    

    它检查表中是否存在@value,如果不存在,则使用0作为默认值。 @值也可以是PHP值。

    希望有帮助:)

        2
  •  2
  •   Lawrence Barsanti    16 年前

    你可以试试这个。我不能百分之百地肯定它会起作用,因为count()是一个聚合函数,但值得一试。

    SELECT b
    FROM table1 
    WHERE a = (
       SELECT
         CASE count(b)
           WHEN 0 THEN :default_value
           ELSE :passed_value 
         END
       FROM table1
       WHERE a = :passed_value
    )
    
        3
  •  1
  •   mike    16 年前

    怎么样

    $rows = $db->fetchAll('select a, b FROM y WHERE a IN (2, 0) ORDER BY a DESC');
    if(count($rows) > 0) {
      $a = $rows[0]['a'];
      $i = 0;
      while($rows[$i]['a'] === $a) {
        echo $rows[$i++]['b']."\n";
      }
    }
    

    一个查询,但如果有很多“零”值,则会产生开销。
    如果你关心开销…

        4
  •  1
  •   Jacob    16 年前

    我认为MichalKralik是基于服务器性能的最佳答案。为这样简单的逻辑执行子选择或存储过程真的不值得。

    我改进michal逻辑的唯一方法是在一个脚本中多次执行这个查询。在本例中,我将首先查询0,然后运行每个单独的查询,然后检查是否有任何值。

    伪码

    // get the value for hte zero's
    $zeros = $db->fetchAll('select a, b FROM y WHERE a = 0');
    
    //checking for 1's
    $ones = $db->fetchAll('select a, b FROM y WHERE a = 1');
    if(empty($ones)) $ones = $zeros;
    
    //checking for 2's
    $twos = $db->fetchAll('select a, b FROM y WHERE a = 2');
    if(empty($twos)) $twos = $zeros;
    
    //checking for 3's
    $threes = $db->fetchAll('select a, b FROM y WHERE a = 3');
    if(empty($threes)) $threes = $zeros;
    
        5
  •  0
  •   Cade Roux    16 年前

    您可以在具有单个参数的单个存储过程中完成所有这些操作。

    我得走了,但我一下班就给你写一份,并把它加在这里。

        6
  •  0
  •   CindyH    16 年前

    我不知道为什么要把这个写下来-请教育我。它是一个有效的、经过测试的存储过程,我回答了这个问题。OP不要求答案是PHP。???

    这里有一个存储过程来执行您希望在SQL Server中工作的操作。我不确定MySQL。

    create proc GetRealElseGetDefault (@key as int)
    as
    begin
    
    -- Use this default if the correct data is not found
    declare @default int
    select @default = 0
    
    -- See if the desired data exists, and if so, get it.  
    -- Otherwise, get defaults.
    if exists (select * from TableY where a = @key)
        select b from TableY where a = @key
    else
        select b from TableY where a = @default
    
    end -- GetRealElseGetDefault
    

    您将(在SQL Server中)使用

    获取区域设置默认值1

    基于快速的谷歌搜索,存在于MySQL中的速度很快。如果A列被编入索引,速度会特别快。如果您的表足够大,可以让您担心性能,那么它可能足够大,可以编制索引。