Ben MySql sonuçlarının sayısına dayalı bir sorgu içine sorgular refactor?

6 Cevap php

Ben iki sütun a ve b var y bir tablo var

Girdileri

a b

1 2

1 ila 3

1 ila 4

0 5

0 2

0 4

Ben sütunu ararsanız ben sütunu a 1 için, ve 5,2,4 ararsanız ben 2,3,4 almak istiyorum a.

Yani A bir şey, için bir arama yaparsanız, (1) Ben bu satırları almak ve verilen değer için herhangi bir kayıt A varsa, bana 'Defaults' (a = '0 'verecek )

İşte ben bunu nasıl bilemez nasıl.

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

Yani, şimdi yeterince açıklanmıştır olduğuna göre, ben nasıl yapabilirim, bir sorguda, ve ne performans kaygıları hakkında ki? Eğer varsayılan sokak IF sadece bir dizi için a değerleri orada olacağını, çünkü en çok kullanılan kısım, üçüncü sorgu olacaktır.

6 Cevap

Ben bunu düşünüyorum:

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 can be a php value too.

Umarım yardımcı olur :)

Sen böyle bir şey deneyebilirsiniz. Sayısı (), bir toplama işlevi ancak değer bir çekim olduğu için işe% 100 emin değilim.

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
)

Ne hakkında

$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...

Ben sunucu performansa dayalı bence Michal Kralik iyi cevabı düşünüyorum. Böyle basit mantık için subselects veya saklanan prosedürleri yapmak gerçekten buna değer değildir.

Eğer bir script bu sorguyu birden çok kez yapıyorsun ben Michal mantığı üzerinde artıracak tek yoludur. Bu durumda ilk 0 en sorgulamak, ve sonra her sorgu çalıştırmak, herhangi bir değer varsa o zaman kontrol ediyorum.

Pseudo-kod

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

Tek bir parametre ile tek bir saklı yordam tüm bu yapabilirsiniz.

Ben dışarı çalıştırmak zorunda, ama ben sizin için bir tane yazmaya çalışacağım ve en kısa sürede geri benim işim olsun burada eklemek gerekir.

Bu aşağı işaretlenmiş neden bilmiyorum - Beni eğitmek lütfen. Bu, geçerli bir test saklı yordam ve ben soruyu yanıtladı. OP cevabı php olmak istemedi. ?

Burada SQL Server çalışır ne istediğinizi yapmak için bir saklı yordam var. MySQL hakkında emin değilim.

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

Sen ile (sql server), bu aday olacağını

GetRealElseGetDefault 1

Hızlı bir google arama dayanarak, mevcut MySQL hızlı. Bu sütun A endeksli özellikle hızlı olacaktır. Lütfen tabloda performansı hakkında endişeli olmak için yeterince büyükse, bu dizine büyük olasılıkla yeterince büyük.