2014-10-02 3 views
6

У меня есть запрос от oracle 11 db. С нижеприведенным запросом я получаю все последние TAG_VALUE, TAG_DESC, INSERTION_DATE and PROJECT_ID из моей базы данных.Запросить только числовые значения самой ранней возможной даты

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; 

Однако я наткнулся случаев, что ответ моего запроса (без ее сортировки по дате) может выглядеть так:

+----------------------------------------------+ 
| 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  | 
+----------------------------------------------+ 

Мой Result Set должен выглядеть так:

+----------------------------------------------+ 
| 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  | 
+----------------------------------------------+ 

Есть два случая, которые в основном фокусируются на одной и той же проблеме:

  • Как видите, есть два случая, когда дата ввода всегда одна и та же. Однако, с моим запросом выше, я все еще получаю null назад из-за ordering. Как я могу получить номер 312 обратно без получения null или значения 0?
  • Если projectID = 2 есть другие даты введения, и более ранние даты были такими, как TAG_VALUEnull элементов. Тем не менее, я хотел бы иметь tagValue| 1234 Equity 19-SEPT-13 2 |, потому что это последнее значение?

Как, я могу в принципе игнорировать все null, а также 0 значения величин и принимать только числовое, что больше, чем 0 значение с самой ранней датой?

Я действительно ценю ваш ответ!

+0

Не удалось исправить ваш запрос: FROM project p FROM updated u – Rusty

+1

Есть ли TAG_VALUE a VARCHAR2 или NUMBER? Это похоже на модель EAV, и если вы используете общий тип данных, ответ будет намного сложнее. –

+0

@JonHeller TAG_Value является ЧИСЛЕННЫМ. Что вы подразумеваете под моделью EAV? – mrquad

ответ

3

Учитывая, что ваша группировка происходит в PROJECT_ID для INSERTION_DATE DESC и положительным TAG_VALUE, я отлажены аналитические функции для достижения результата. Это не может быть надежным решением, но, безусловно, поможет вам.

Настройка данных:

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 
; 

Запрос:

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; 

Результат:

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 

Вот fiddle

1

Вы можете выбрать min (Insertion_Date) и идентификатор проекта во внутреннем запросе из таблицы и отфильтровать его с помощью Tag_Value <> Null. Затем во внешнем запросе внутреннее соединение таблицы с этим внутренним запросом на project_id и insertion_date.

+0

Не могли бы вы добавить пример с помощью примерного запроса? Что именно вы подразумеваете под 'select min (Insertion_Date) и ID проекта во внутреннем запросе из таблицы и фильтруете его с помощью Tag_Value <> Null.' – mrquad

+0

Выберите * из таблицы присоединитесь (Выберите PROJECT_ID, min (INSERTION_DATE) из таблицы где Tag_Value <> Null группы по проекту ID) – Xion

+0

Select * из таблицы t1 присоединиться (Select PROJECT_ID, мин (INSERTION_DATE) из таблицы где Tag_Value <> Null группы по проекту ID) t2 по t1.Project_id = t2.project_id и t1.insertion_date = t2.insertion_date «таблица» здесь может быть вашей фактической таблицей или выпиской, которую вы упомянули в вопросе. – Xion

1

Пример использования 1:

Если я правильно понял ваши варианты использования, вы можете сделать это с помощью «приоритетов» из ненулевым-ненулевых tag_value -s в пункте Упорядочивание аналитической функции, как показано ниже :

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 

Это, конечно, даст вам null -s или нули в вашем выводе каждый раз нет других tag_value -s в вашем разделе данных идентифицированных p.proj_id.


Пример использования 2:

Если вы хотите избавиться от нулей и null -s полностью, вам придется изменить положение вашего (внутреннего) запроса where вместо:

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

Ваш вопрос: «Как, я могу в принципе игнорировать все нулевые, а также 0 значения значения»

Простой ответ: удалить эти записи в предложении WHERE.

Я использую AND t.tag_value > 0 здесь. Вы можете заменить его AND t.tag_value <> 0 AND t.tag_value IS NOT NULL, если вы хотите разрешить отрицательные значения.

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; 
Смежные вопросы