简体   繁体   English

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

[英]Can I refactor my MySQL queries into one query based on number of results?

I have a table y Which has two columns a and b 我有一个表y其中有两列ab

Entries are: 条目是:

a   b

1   2

1   3

1   4

0   5

0   2

0   4

I want to get 2,3,4 if I search column a for 1, and 5,2,4 if I search column a . 我想2,3,4如果我搜索栏a 1,和5,2,4如果我搜索列a

So, if I search A for something that is in A, (1) I get those rows, and if there are no entries A for given value, give me the 'Defaults' ( a = '0') 因此,如果我在A中搜索A中的内容,(1)我会得到这些行,并且如果没有给定值的条目A,请给我'Defaults'( a ='0')

Here is how I would know how to do it: 这是我怎么知道的方法:

$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;');

So, now that it's sufficiently explained, how do I do that in one query, and what about performance concerns? 那么,既然已经充分解释了,我该如何在一个查询中进行操作,以及对性能的关注呢?

The most used portion would be the third query, because there would only be values in a for a number IF you stray from the defaults. 最常用的部分将是第三个查询,因为如果您偏离默认值,则数字a中将只包含值。

You can try something like this. 您可以尝试这样。 I'm not 100% sure it will work because count() is a aggregate function but its worth a shot. 我不确定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
)

I think I have it: 我想我有:

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

It checks if @value exists in the table, if not, then it uses 0 as a default. 它检查表中是否存在@value,如果不存在,则使用0作为默认值。 @value can be a php value too. @value也可以是php值。

Hope it helps :) 希望能帮助到你 :)

What about 关于什么

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

One query, but overhead if there are a lot of 'zero' values. 一个查询,但是如果有很多“零”值,则开销很大。
Depends if you care about the overhead... 取决于您是否在乎开销...

I think Michal Kralik best answer in my opinion based on server performance. 我认为基于服务器性能,Michal Kralik认为是最佳答案。 Doing subselects or stored procedures for such simple logic really is not worth it. 对于这样简单的逻辑进行子选择或存储过程确实不值得。

The only way I would improve on Michal's logic is if you are doing this query multiple times in one script. 我要改善Michal逻辑的唯一方法是,如果您在一个脚本中多次执行此查询。 In this case I would query for the 0's first, and then run each individual query, then checking if there was any value. 在这种情况下,我将首先查询0,然后运行每个查询,然后检查是否有任何值。

Pseudo-code 伪码

// 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;

You can do all this in a single stored procedure with a single parameter. 您可以使用单个参数在单个存储过程中完成所有这些操作。

I have to run out, but I'll try to write one up for you and add it here as soon as I get back from my errand. 我必须精疲力尽,但我会尽力为您写一份,并在您差事回来后将其添加到这里。

I don't know why this was marked down - please educate me. 我不知道为什么将此标记为低-请教育我。 It is a valid, tested stored procedure, and I answered the question. 这是一个有效的,经过测试的存储过程,我回答了这个问题。 The OP didn't require that the answer be in php. OP不需要答案在php中。 ?? ??

Here's a stored proc to do what you want that works in SQL Server. 这是一个存储的proc,它可以执行您希望在SQL Server中工作的程序。 I'm not sure about MySQL. 我不确定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

You would run this (in sql server) with 您可以使用以下命令运行此命令(在sql server中)

GetRealElseGetDefault 1 GetRealElseGetDefault 1

Based on a quick google search, exists is fast in MySQL. 基于快速的Google搜索,MySQL中存在的速度很快。 It would be especially fast is column A is indexed. 如果对列A进行索引,这将特别快。 If your table is large enough for you to be worried about performance, it is probably large enough to index. 如果您的表足够大以至于您担心性能,那么它可能足够大以进行索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM