2010-06-20 10 views
11

Aynı tablodaki bir satırın iki sütunundaki en düşük sayıyı bulmaya çalışıyorum; sütunlardan birinin belirli bir satırda boş olabileceğini belirten bir uyarı. Sütunlardan biri boşsa, diğer sütundaki değerin bu satır için döndürmesini istiyorum, çünkü bu durumda en düşük sıfır olmayan sütun olur. Ben MySQL 5.1 en az() fonksiyonunu kullanıyorsanız:SQL'de belirli bir satırda en az sıfır olmayan sütun nasıl bulunur?

select least(1,null) 

Bu ne istiyorum olmadığı, null döndürür. Bu durumda 1 dönmek için sorguya ihtiyacım var.

Ben bu sorgu ile genel olarak istediğiniz sonucu elde etmek mümkün oldum: col1 sürece

select least(coalesce(col1, col2)) , coalesce(col2,col1)) 

ve col2 hem boş değil her deyim bir sayı döndürür yapışkanlaşmakta ve en az (En düşük bulmak için kolları.

Bunu yapmanın daha basit/daha hızlı bir yolu var mı? Bu durumda MySQL kullanıyorum ama genel çözümler memnuniyetle karşılıyor. Bu biraz daha iyi performans gösterebilir

+1

hızlı? Yavaş olmaya karar verdin mi? –

+0

Mutlaka yavaş olması gerektiğine karar vermedim, ancak bir tanesi yerine 3 fonksiyon çağırıyor. Bir sorguyu bir sıraya göre kullanıyorum, olabildiğince hızlı olmalıyım. –

cevap

11

(sizin durumunuza göre) LEAST'in davranışı MySQL 5.0.13'te (http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_least) değiştirildi - yalnızca tüm argümanlar NULL ise NULL değerini döndürmek için kullanılır.

Bu değişiklik bir hata olarak bildirildi: http://bugs.mysql.com/bug.php?id=15610 Ancak düzeltme yalnızca yeni davranış ve uyumluluk açıklamasını açıklayan MySQL belgelerine yönelikti.

Çözümünüz, önerilen geçici çözümlerden biriydi. Operatör IF Başka kullanarak edilebilir:

SELECT IF(Col1 IS NULL OR Col2 IS NULL, COALESCE(Col1, Col2), LEAST(Col1,Col2)) 
3

(MySQL sözdizimi bir azotu gerekebilir):

SELECT 
    CASE 
    WHEN Col1 IS NULL THEN Col2 
    WHEN Col2 IS NULL THEN Col1 
    ELSE Least(Col1, Col2) 
    END 

başka alternatifi (gerçi muhtemelen daha yavaş, ama bir cami): Maalesef

SELECT Col1 
WHERE Col2 IS NULL 
UNION 
SELECT Col2 
WHERE Col1 IS NULL 
UNION 
SELECT least(Col1, Col2) 
WHERE Col1 IS NOT NULL AND Col2 IS NOT NULL 
3

tüm değerler null olmak zorunda da köşe vaka Duruma bağlı olarak, ben (eğer tam olarak iki sütun varsa daha kolay bir çözüm altındadır daha okunabilir böyle sözdizimi için giderdim !)

o en az bir sütun sağlayabilirsiniz

  • eğer benim tercih edilen yöntem
    SELECT LEAST(IFNULL(5, ~0 >> 1), IFNULL(10, ~0 >> 1)) AS least_date; 
    -- Returns: 5 
    
    SELECT LEAST(IFNULL(null, ~0 >> 1), IFNULL(10, ~0 >> 1)) AS least_date; 
    -- Returns: 10 
    
    SELECT LEAST(IFNULL(5, ~0 >> 1), IFNULL(null, ~0 >> 1)) AS least_date; 
    -- Returns: 5 
    
    SELECT LEAST(IFNULL(null, ~0 >> 1), IFNULL(null, ~0 >> 1)) AS least_date 
    -- Returns: @MAX_VALUE (If you need to use it as default value) 
    
    SET @MAX_VALUE=~0 >> 1; 
    SELECT LEAST(IFNULL(null, @MAX_VALUE), IFNULL(null, @MAX_VALUE)) AS least_date; 
    -- Returns: @MAX_VALUE (If you need to use it as default value). Variables just makes it more readable! 
    
    SET @MAX_VALUE=~0 >> 1; 
    SELECT NULLIF(
        LEAST(IFNULL(null, @MAX_VALUE), IFNULL(null,@MAX_VALUE)), 
        @MAX_VALUE 
    ) AS least_date; 
    -- Returns: NULL 
    

    can olmayacak NULL

  • Köşe durum durumunda (tüm sütunlar NULL), olası herhangi bir değerden daha büyük olmayan veya belirli bir eşiğe sınırlı olan boş bir varsayılan değer istiyorsanız
  • Bu ifadeyi daha okunaklı hale getirmek için değişkenlerle başa çıkabilir

~0 >> 1'un ne anlama geldiğini kendiniz sorarsanız: Sadece "Bana en büyük numarayı ver" deyişi için kısa bir el.Ayrıca bakınız: https://stackoverflow.com/a/2679152/2427579

Daha da iyisi, sadece iki sütun varsa, kullanabilirsiniz: NULL olduğunda

SELECT LEAST(IFNULL(@column1, @column2), IFNULL(@column2, @column1)) AS least_date; 
-- Returns: NULL (if both columns are null) or the least value 
0

Neden diğer kolona eşit olacak şekilde bir sütunun değerini ayarlanmamış? Yukarıdaki kodla birlikte, her ikisi de boş olmadıkça, boş değer göz ardı edilecektir .

örn.

Col1 = NULL, COL2 = 5

LEAST(IFNULL(NULL, 5), IFNULL(5, NULL)) -> LEAST(5, 5) -> 5 

Col1 = 3, COL2 = BOŞ

LEAST(IFNULL(3, NULL), IFNULL(NULL, 3)) -> LEAST(3, 3) -> 3 

Col1 = NULL, COL2 = BOŞ

LEAST(IFNULL(NULL, NULL), IFNULL(NULL, NULL)) -> LEAST(NULL, NULL) -> NULL 
İlgili konular