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

时间:2020-03-06 14:29:06  来源:igfitidea点击:

我有一个表" y",其中有两列" a"和" b"

条目是:

a   b

1   2

1   3

1   4

0   5

0   2

0   4

如果我搜索列" a"中的1,我想得到2,3,4,如果我搜索列" a"中,我想得到5,2,4.

因此,如果我在A中搜索A中的内容,(1)我会得到这些行,并且如果没有给定值的条目A,请给我'Defaults'('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;');

那么,既然已经充分解释了,我该如何在一个查询中进行操作,以及对性能的关注呢?

最常用的部分是第三个查询,因为如果我们偏离默认值,那么在a中只有一个值。

解决方案

我们可以使用单个参数在单个存储过程中完成所有这些操作。

我必须精疲力尽,但我会尽力为我们写一份,并在我们差事回来后将其添加到这里。

我不知道为什么将其标记为低,请教育我。这是一个有效的,经过测试的存储过程,我回答了这个问题。 OP不需要答案在php中。 ??

这是一个存储的proc,用于执行我们希望在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中)

GetRealElseGetDefault 1

基于快速的Google搜索,MySQL中存在的速度很快。如果对A列进行索引,这将特别快。如果表足够大以至于我们担心性能,那么它可能足够大以进行索引。

我们可以尝试这样的事情。我不确定100%会起作用,因为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
)

关于什么

$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";
  }
}

一个查询,但如果有很多"零"值,则开销很大。
取决于我们是否在乎开销...

我想我有:

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

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

希望能帮助到你 :)

我认为基于服务器性能,Michal Kralik认为是最佳答案。对于这样简单的逻辑进行子选择或者存储过程确实不值得。

我要改善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;