2014-10-02 11 views
6

Mam do zapytania od oracle 11 db. W poniższym zapytaniu otrzymuję wszystkie najnowsze TAG_VALUE, TAG_DESC, INSERTION_DATE and PROJECT_ID z mojej bazy danych.Wypytuj tylko wartości numeryczne najwcześniejszej możliwej daty.

SELECT * 
FROM (SELECT t.tag_value, 
       t.tag_desc, 
       u.update_as_of     AS INSERTION_DATE, 
       p.proj_id       AS PROJECT_ID, 
       Row_number() 
       over( 
        PARTITION BY p.proj_id 
        ORDER BY u.update_as_of DESC) RN 
     FROM project p 
       join update u 
       ON p.project_id = u.project_id 
       join tag t 
       ON t.tag_id = u.tag_id 
     WHERE t.tag_desc LIKE 'Equity%') 
WHERE rn = 1; 

Jednak doszedłem po drugiej przypadków, że odpowiedź na moją prośbę (bez sortowania je według daty) może wyglądać tak:

+----------------------------------------------+ 
| TAG_VALUE TAG_DESC INSERTION_DATE PROJECT_ID | 
+----------------------------------------------+ 
| null  Equity 14-DEC-14  1  | 
| 0   Equity 14-DEC-14  1  | 
| 312   Equity 14-DEC-14  1  | 
| 23343  Equity 17-DEC-11  5  | 
| 1263  Equity 16-DEC-11  5  | 
| null  Equity 22-JÄN-14  2  | 
| null  Equity 11-JÄN-14  2  | 
| null  Equity 25-SEPT-13  2  | 
| 0   Equity 20-SEPT-13  2  | 
| 1234  Equity 19-SEPT-13  2  | 
| 13415  Equity 18-SEPT-13  2  | 
| 99999  Equity 16-OCT-10  9  | 
+----------------------------------------------+ 

Moja Result Set powinien wyglądać tak:

+----------------------------------------------+ 
| TAG_VALUE TAG_DESC INSERTION_DATE PROJECT_ID | 
+----------------------------------------------+ 
| 312   Equity 14-DEC-14  1  | 
| 23343  Equity 17-DEC-11  5  | 
| 1234  Equity 19-SEPT-13  2  | 
| 99999  Equity 16-OCT-10  9  | 
+----------------------------------------------+ 

Istnieją dwa przypadki, które zasadniczo koncentrują się na tym samym problemie:

  • Jak widać, istnieją dwa przypadki, kiedy project_id = 1 data wstawienia jest zawsze taka sama. Jednak z mojego zapytania powyżej nadal otrzymuję null z powrotem z powodu ordering. Jak mogę odzyskać numer 312 bez uzyskiwania wartości null lub 0?
  • Jeśli projectID = 2 istnieją różne daty wstawiania, a wcześniejsze daty mają elementy TAG_VALUEnull. Jednak chciałbym mieć tagValue z | 1234 Equity 19-SEPT-13 2 |, ponieważ jest to najnowsza wartość?

Jak mogę po prostu zignorować wartości wszystkich null a także 0 wartości i tylko wziąć numeryczna, która jest większa niż wartość 0 z najwcześniejszą datą?

Naprawdę doceniam twoją odpowiedź!

+0

Proszę poprawić zapytanie: Z projektu p Z aktualizacji u – Rusty

+1

Czy TAG_VALUE to VARCHAR2 lub NUMBER? To wygląda jak model EAV, a jeśli używasz typowego typu danych, odpowiedź będzie znacznie bardziej skomplikowana. –

+0

@JonHeller Wartość parametru TAG_Value jest NUMERYCZNA. Co masz na myśli, mówiąc o modelu EAV? – mrquad

Odpowiedz

3

Biorąc pod uwagę, że grupowanie się dzieje wewnątrz PROJECT_ID dla INSERTION_DATE DESC i pozytywnego TAG_VALUE, ja manipulowane funkcje analityczne do osiągnięcia rezultatu. To może nie być solidne rozwiązanie, ale na pewno ci pomoże.

danych Setup:

CREATE TABLE Table1 
    ("TAG_VALUE" varchar2(5), "TAG_DESC" varchar2(6), "INSERTION_DATE" varchar2(10), "PROJECT_ID" int) 
; 

INSERT ALL 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES (NULL, 'Equity', '14-DEC-14', 1) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('0', 'Equity', '14-DEC-14', 1) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('312', 'Equity', '14-DEC-14', 1) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('23343', 'Equity', '17-DEC-11', 5) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('1263', 'Equity', '16-DEC-11', 5) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES (NULL, 'Equity', '22-JÄN-14', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES (NULL, 'Equity', '11-JÄN-14', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES (NULL, 'Equity', '25-SEPT-13', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('0', 'Equity', '20-SEPT-13', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('1234', 'Equity', '19-SEPT-13', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('13415', 'Equity', '18-SEPT-13', 2) 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID") 
     VALUES ('99999', 'Equity', '16-OCT-10', 9) 
SELECT * FROM dual 
; 

Zapytanie:

SELECT tag_value, 
     tag_desc, 
     insertion_date, 
     project_id 
FROM (SELECT tag_value, 
       tag_desc, 
       insertion_date, 
       project_id, 
       Last_value(Decode(tag_value, 0, NULL, 
              tag_value) ignore nulls) 
       over ( 
        PARTITION BY project_id 
        ORDER BY insertion_date ROWS BETWEEN unbounded preceding AND 
       unbounded 
       following) new_tag_value 
     FROM table1) 
WHERE tag_value = new_tag_value; 

Wynik:

TAG_VALUE TAG_DESC INSERTION_DATE PROJECT_ID 
312   Equity  14-DEC-14  1 
1234  Equity  19-SEPT-13  2 
23343  Equity  17-DEC-11  5 
99999  Equity  16-OCT-10  9 

Oto fiddle

1

Możesz wybrać min (Insertion_Date) i ID projektu w zapytaniu wewnętrznym z tabeli i przefiltrować je według zmiennej Tag_Value <> Null. Następnie w zapytaniu zewnętrznym wewnętrznie dołączamy do tabeli z tą wewnętrzną kwerendą na project_id i insertion_date.

+0

Czy możesz dodać przykład za pomocą przykładowego zapytania? Co dokładnie masz na myśli, wybierając 'min (Insertion_Date) i ID projektu w zapytaniu wewnętrznym z tabeli i odfiltruj je według zmiennej Tag_Value <> Null. – mrquad

+0

Wybierz * z tabeli dołącz (wybierz PROJECT_ID, min (INSERTION_DATE) z tabeli gdzie Tag_Value <> zerowa grupa przez ID projektu) – Xion

+0

Select * z tabeli T1 przyłączenia (Wybór PROJECT_ID min (INSERTION_DATE) z tabeli gdzie Tag_Value <> zerowa grupa przez ID projektu) t2 na t1.Project_id = t2.project_id i t1.insertion_date = t2.insertion_date "Tabela" w tym miejscu może być rzeczywistą tabelą lub stwierdzeniem, które wymieniono w pytaniu. – Xion

1

Wykorzystanie case 1:

Gdybym zrozumiał swoje przypadki użycia prawidłowo, można to zrobić poprzez „priorytetów” z non-null niezerowych tag_value -s w klauzuli zamawiania funkcji analitycznej w następujący sposób :

ROW_NUMBER() OVER (
    PARTITION BY p.proj_id 
    ORDER BY 
     CASE WHEN t.tag_value > 0 THEN 0 ELSE 1 END ASC, 
     u.update_as_of DESC 
) RN 

To, oczywiście, daje null -s lub zer w swoim wyjściu za każdym razem nie ma żadnych innych tag_value -s twojej partycji danych wskazanych przez p.proj_id.


Wykorzystanie case 2:

Jeśli chcesz pozbyć się zer i null -s całkowicie, musisz zmodyfikować klauzuli swojego (wewnętrznej) zapytania where zamiast:

WHERE t.tag_desc LIKE 'Equity%' 
    AND t.tag_value > 0 
3

Twoje pytanie brzmi: „Jak mogę po prostu zignorować wszystkie zerowe, a także 0 Wielkości”

Prosta odpowiedź brzmi: Usuwając te rekordy w klauzuli WHERE.

Używam tutaj AND t.tag_value > 0. Możesz go zastąpić wartością AND t.tag_value <> 0 AND t.tag_value IS NOT NULL, jeśli chcesz zezwolić na wartości ujemne.

SELECT * 
FROM 
(
    SELECT 
    t.tag_value, 
    t.tag_desc, 
    u.update_as_of AS INSERTION_DATE, 
    p.proj_id AS PROJECT_ID, 
    ROW_NUMBER() OVER(PARTITION BY p.proj_id ORDER BY u.update_as_of DESC) RN 
    FROM updated u 
    JOIN project p ON p.project_id = u.project_id 
    JOIN tag t ON t.tag_id = u.tag_id 
    WHERE t.tag_desc LIKE 'Equity%' AND t.tag_value > 0 
) 
WHERE RN = 1; 
Powiązane problemy