Sol dış birleşim için bir varsayılan sağlayabilir miyim?


21

Tablo a (sütun a1 ile) ve b (sütun b1 ve b2 ile) ve sol dış birleşim yaptığımı varsayalım

SELECT *
FROM a LEFT OUTER JOIN b
ON a.a1 = b.b1

Daha sonra b1 ve b2 NULL olur, burada a1 değeri b1 ile eşleşen bir değere sahip olmaz.

B2 için NULL yerine varsayılan bir değer sağlayabilir miyim? Çünkü COALESCE, burada çalışmaz Not yok orada burada b2 potansiyel boş değerlere geçersiz kılmak varsayılan değeri istiyoruz olan b1 eşleştirme a1 değeri olabilir.

Yani, a ve b ile

CREATE TABLE a (a1)
  AS VALUES (1),
            (2),
            (3) ;

CREATE TABLE b (b1,b2)
  AS VALUES (1, 10),
            (3, null) ;


a1     b1 | b2
---    --------
 1      1 | 10
 2      3 | NULL
 3

ve b2 için bir varsayılan, örneğin, 100, sonuç almak istiyorum

a1 | b1   | b2
---------------
1  |  1   | 10
2  | NULL | 100
3  |  3   | NULL

Bu basit durumda çıktıda b1 NULL olup olmadığına bakarak "elle" yapabilirim. Genel olarak en iyi seçenek mi yoksa daha standart ve daha düzgün bir yol var mı?

Yanıtlar:


23
SELECT a.a1,b.b1,  
    CASE WHEN b.b1 is NULL THEN 5 ELSE b.b2 END AS b2  
FROM a LEFT OUTER JOIN b  
ON a.a1 = b.b1

2
Lütfen soru yalnızca etiketlendiğinde ANSI SQL kullanın sql(yani "SQL sorgu dili" anlamına gelir. Bu etiket herhangi bir DBMS ürününü veya lehçesini göstermez). Bölüm: [b2]=CASE WHEN ... ENDgeçersiz (standart) bir SQL ifadesidir.
a_horse_with_no_name

Postgres'e özel bir yanıtı kabul edeceğimi belirten bir etiket ekledim. Yine de mümkünse standart SQL tercih edilecektir.
Tom Ellis

@Kin: sorumda belirtildiği gibi, b1 çıktıda NULL olup olmadığına bakarak "elle yapabilirim" olduğunu biliyorum. Genel olarak en iyi seçenek mi yoksa daha standart ve daha düzgün bir yol var mı? "
Tom Ellis

3
bir JOIN nedeniyle oluşan ve "doğal" olarak mevcut olan NULL'ları ayırmak istediğiniz için, b1'i incelemeniz kaçınılmazdır. Eğer "elle yapabilirim" ile kastettiğin buysa, evet, tek yol budur.
Mordechai

@MorDeror: Tamam, sanırım "SOL DIŞ BİRLEŞME ... AÇIK ... VARSAYILAN b2 = ..." gibi bir sözdizimi olabileceğini düşünüyordum.
Tom Ellis

2

Bu sorunun orijinal cevabı açıklanamadı, bu yüzden buna başka bir şans verelim.

Bir Kullanarak CASEdeyimi

Bu yöntemi kullanarak , farklı bir sütunda başka bir değere sahip olduğumuzuIS NOT NULL ve bu durumda b.b1bu değer null ise birleştirmenin başarısız olduğunu bildiğimizden yararlanırız.

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b.b1 is NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN b  
  ON (a.a1 = b.b1);

Bu tamamen işe yarayacak ve tam olarak istediğiniz şeyi üretecektir.

Bir alt SELECT kullanma

Bu yöntemi kullanma, bu birikim fikri. Okumaya devam et.

BuNOT NULL şekilde yararlanabileceğimiz sütunlarımız yoksa , bizim için bu şekilde işlev görebilecek bir sütun oluşturmak için bir şeye ihtiyacımız var ...

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b.cond IS NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN (
  SELECT true AS cond, b.*
  FROM b
) AS b
  ON (a.a1 = b.b1);

Satır karşılaştırması kullanma

Ancak daha da kolaylaştırabildiğimiz yanlış bir değeri zorlamak, satırı karşılaştırmaktır. PostgreSQL'de, satır tablonun adına göre bir değere sahiptir. Örneğin , tablodan bir tür satır (satır türü) SELECT foo FROM foodöndürür . Burada ROW'un boş olup olmadığını test ediyoruz. Bu, her sütun kadar çalışacaktır . Ve tablonuzdaki her sütun varsa , o zaman sadece troll ediyorsunuz.foofooIS NOT NULLIS NULL

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b IS NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN b
  ON (a.a1 = b.b1);

Kolon b1kullanılan CASEsolüsyon olmayan null olması gerekmez. İnşaat her iki durumda da çalışır.
ypercubeᵀᴹ

1

COALESCE'ın bu durumda çok yararlı olduğunu düşünüyorum. Listeden ilk NULL olmayan değeri döndürür:

SELECT
 a.a1,
 b.b1,
 COALESCE (b.b2, 100) AS b2
FROM a
LEFT OUTER JOIN b
  ON (a.a1 = b.b1);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.