oracle

2016-03-26 31 views
0

mevcut satırların sayısına göre tek bir satır seçin Bir sorgu kullanarak aşağıdaki tabloya sahibim: Şimdi tek bir kaydı aşağıda açıklanan koşullara göre almak istiyorum ve saklı yordamımda bildirilen iki değişkeni yani v_dte_meeting ve v_status_meeting olarak atamak istiyorumoracle

  1. Status_Meeting ile mevcut aa tek veya birden fazla kayıt olarak 'Due' Sonra birlikte büyük tarihi v_dte_meeting atamak 'Due' yaparsanız:
    Dte_Meeting| Ststus_Meeting 
    ######################## 
    15-Oct-14 | Due  
    30-Oct-14 | Due 
    15-Dec-14 | Init 
    30-Dec-14 | Init 
    30-Nov-15 | Approved 
    

    Ben koşullar altında dayanarak bu değişkenlere değer atamak istiyoruz durumu ve v_status_meeting wi atamak th değeri 'Due'
  2. Yukarıdaki koşul başarısız olursa, Check in Ststus_Meeting ile bir veya birden fazla kayıt Varsa, 'Init' olarak görünüyorsa, o zaman 'Init' durumuyla en büyük tarihi v_dte_meeting atayın ve v_status_meeting değerini 'Init ile atayın '
  3. hem durum her iki değişkenler BOŞ değer

atamak başarısız olursa beni Oracle'da bunu en iyi şekilde yapmak için yardım edin

+0

Sen soruyu düzenlemek ve beklenen sonuçları sağlamalıdır. –

cevap

0

Bu yardımcı olur umarım. Ben sadece SELECT ifadesini gösteriyorum (değişkenler yaratmadım, bu yüzden INTO'yu seçmiyorum, fakat bu sizin zorluğunuz değildi, bunu nasıl yapacağınızı biliyorsunuz.) Alt sorgu faktoringini (WITH yan tümcesi) kullanıyorum, yalnızca sürümleri> = 11 inanıyorum, aksi takdirde ait oldukları alt sorguları koymak için yeniden yazabilirsiniz.

Kullanım sıralaması not(); Gordon'un çözümünde, sadece statüleri olan 'değil' olanları değil, ALL satırları üzerinde maksimum (dte) toplayacaktır, bu yüzden yazdığı kadar basit olamaz. EDIT: Ayrıca 'Due' veya 'Init' yoksa ne NULL, NULL'u seçtiğini görmüyorum. (Maalesef kötüye için, bu şimdiye ayrıcalıkları yoksun, onun cevabı bir açıklama olmalıdır.)

WITH t (Date_Meeting, Status_Meeting) AS 
    (
     SELECT TO_DATE('15-OCT-14', 'DD-MON-YY'), 'Due' FROM dual UNION ALL 
     SELECT TO_DATE('30-OCT-14', 'DD-MON-YY'), 'Due' FROM dual UNION ALL 
     SELECT TO_DATE('15-DEC-14', 'DD-MON-YY'), 'Init' FROM dual UNION ALL 
     SELECT TO_DATE('30-DEC-14', 'DD-MON-YY'), 'Init' FROM dual UNION ALL 
     SELECT TO_DATE('15-NOV-15', 'DD-MON-YY'), 'Approved' FROM dual 
    ), 
    s (Date_Meeting, Status_Meeting) AS 
    (
     SELECT Date_Meeting, Status_Meeting FROM t 
      WHERE Status_Meeting = 'Due' OR Status_Meeting = 'Init' 
     UNION ALL SELECT NULL, NULL FROM dual -- To ensure you have the nulls if needed 
    ), 
    r (Date_Meeting, Status_Meeting, rk) AS 
    (
     SELECT Date_Meeting, Status_Meeting, 
      RANK() OVER (ORDER BY DECODE(Status_Meeting, 'Due', 0, 'Init', 1, 2), 
          Date_Meeting DESC) -- make sure you understand this 
     FROM s 
    ) 
SELECT Date_Meeting, Status_Meeting FROM r WHERE rk = 1 
/

Sonuç:

DATE_MEET STATUS_M 
--------- -------- 
30-OCT-14 Due 

1 row selected. 
+0

evet .. Max (dte) kullanarak çözümün yanlış olduğunu fark ettim, çözümünüz gayet iyi çalıştı ama sadece bir tane dış sorgu kullanmak istemedim. (Biliyorum cte 'r' burada ortadan kaldırılabilir) I tek bir dış sorgu ile grup kullanarak başka bir şekilde yaptım. Hala sadece merak ediyorum, CTE kullanarak alt sorgu üzerinde herhangi bir performans avantajı var mı? – UDS

+0

Sadece aynı alt sorguyu birden fazla yerde yazmamaktan kaçının. Aksi takdirde muhtemelen aynıdır (derleme zamanında, "r" bir alt sorgu olarak yeniden yazılır, bu nedenle uygulamada fark yaratmaz). En büyük fark, kodunuzun okunabilirliğidir ve bu sayede bakımı kolaylaştırır. – mathguy

0

bir yöntem kullanır toplama:

select (case when sum(case when status_meeting = 'Due' then 1 else 0 end) > 0 
      then max(case when status_meeting = 'Due' dte_meeting end) 
      when sum(case when status_meeting = 'Init' then 1 else 0 end) > 0 
      then max(case when status_meeting = 'Init' then dte_meeting end) 
     end), 
     (case when sum(case when status_meeting = 'Due' then 1 else 0 end) > 0 
      then'Due' 
      when sum(case when status_meeting = 'Init' then 1 else 0 end) > 0 
      then 'Init' 
     end) 
into v_dte_meeting, v_status_meeting 
from t; 

Ancak, daha basit bir versiyonu sadece order by kullanır düşünüyorum:

select max(dte_meeting), max(status_meeting) 
into v_dte_meeting, v_status_meeting 
from (select t.* 
     from t 
     where status_meeting in ('Due', 'Init') 
     order by (case when status_meeting = 'Due' then 1 
        when status_meeting = 'Init' then 2 
       end) 
    ) t 
where rownum = 1; 

max() sadece tam olarak bir satır döndürülür sağlamaktır.