2015-05-13 4 views
2

Мне нужно получить различные значения как столбца, так и строки. Oracle SQL-запрос в текущей настройке приведена ниже:Oracle sql different query

select distinct ym.wh_id, 
ym.trlr_num, 
ym.arrdte, 
ri.invnum, 
ri.supnum 
from rcvinv ri, yms_ymr ym 
where ym.trlr_cod='RCV' 
and ri.trknum = ym.trlr_num 
and ym.wh_id <=50 
and ym.trlr_stat in ('C','CI','R','OR') 
and ym.arrdte is not null 
order by ym.arrdte desc; 

Вышеприведенные возвращает результат следующим образом:

> Trailer Number  Arrived  PO    Vendor 
> Trailer4    5/12/2015 010025790692 00101 
> Trailer5-V6661  5/12/2015 010025754823 00110 
> Trailer2-V6651  5/12/2015 010025781421 55395 
> TRAILERS1-V6641  5/12/2015 010025790388 00915 
> DEV110501-V6631  5/11/2015 010025790692 00101 
> Rj-V6621    5/11/2015 010025790692 00101 
> 12345-V6601   5/8/2015 010025751682 00128 
> 12345-V6601   5/8/2015 010025754823 00110 

Я требую вывода следующим образом:

> Trailer Number  Arrived  PO    Vendor 
> Trailer4    5/12/2015 010025790692 00101 
> Trailer5-V6661  5/12/2015 010025754823 00110 
> Trailer2-V6651  5/12/2015 010025781421 55395 
> TRAILERS1-V6641  5/12/2015 010025790388 00915 
> 12345-V6601   5/8/2015 010025751682 00128 

Как вам видно, что повторные выходы для PO (010025790692 и 010025754823) и номер трейлера (12345-V6601) были удалены.

Итак, я хочу изменить запрос таким образом, чтобы я получал отличную от строки и столбца, как в приведенном ниже примере. Пожалуйста, помогите. Благодарю.

+1

Вы должны решить, на какой основе различных значений для столбца выбраны - то почему вы выбираете «Trailer4» для ПО «010025790692», а не "DEV110501-V6631"? – Raad

+0

Привет, Раад. Условие заключается в том, что последний трейлер или самый верхний из них учитывается с помощью ПО. Поэтому, если у многих трейлеров есть одно ПО, то учитывается последний номер трейлера.Аналогично случай, когда есть несколько PO и один трейлер. Отображается последняя версия PO, а остальные опущены. –

ответ

1

Вы можете использовать Analytic ROW_NUMBER(). См. SQL Fiddle.

Например,

SQL> SELECT trailer_number, 
    2 po, 
    3 vendor 
    4 FROM 
    5 (SELECT t.*, 
    6  row_number() OVER(PARTITION BY po, vendor ORDER BY po, vendor) rn 
    7 FROM t 
    8 ) 
    9 WHERE rn = 1; 

TRAILER_NUMBER     PO    VENDOR 
--------------- -------------------- -------------------- 
12345-V6601    10025751682     128 
Trailer5-V6661   10025754823     110 
Trailer2-V6651   10025781421    55395 
TRAILERS1-V6641   10025790388     915 
Trailer4     10025790692     101 

SQL> 

Update OP хочет знать, как применить аналитическую функцию по своему первоначальному запросу:

Ваш измененный запрос будет выглядеть следующим образом:

WITH t AS 
    (SELECT DISTINCT ym.trlr_num trlr_num, 
    ym.arrdte arrdte, 
    ri.invnum invnum, 
    ri.supnum supnum 
    FROM rcvinv ri, 
    yms_ymr ym 
    WHERE ym.trlr_cod ='RCV' 
    AND ri.trknum  = ym.trlr_num 
    AND ym.wh_id  <=50 
    AND ym.trlr_stat IN ('C','CI','R','OR') 
    AND ym.arrdte IS NOT NULL 
), 
    t1 AS (
    SELECT t.trlr_num, 
    t.arrdte, 
    t.invnum, 
    t.supnum, 
    row_number() OVER (PARTITION BY t.trlr_num, t.invnum ORDER BY t.trlr_num, t.invnum DESC) rn 
    FROM t 
) 
SELECT trlr_num, arrdte, invnum, supnum 
    FROM t1 
    WHERE rn = 1; 

Оператор WITH будет разрешен как временная таблица, поэтому вам не нужно создавать любая статическая таблица.

+0

Спасибо, Лалит. Фактически этот запрос извлекается из базы данных в отчет и, следовательно, может быть больше значений, которые будут меняться. Есть ли способ изменить существующий запрос без создания таблицы? –

+0

Я создал таблицу, чтобы показать пример, вам не нужно создавать таблицу, просто используйте запрос и используйте ваше имя для табуляции вместо «t». –

+0

Не могли бы вы помочь мне создать временную таблицу для полей из таблиц yms_ymr и rcvinv, а затем использовать эту таблицу в запросе sql, т. Е. Используя rownum() и partition by. Я думаю, что тогда этот запрос должен получить правильно. –

1

Ваш запрос может быть написан как: Получите последнюю запись за вторник. Вы получаете это путем нумерации (т. Е. С использованием ROW_NUMBER) строк на invnum (то есть PARTITON BY invnum) в желаемом порядке, так что последняя запись получает № 1 (ORDER BY ym.arrdte DESC). Как только нумерация будет выполнена, вы удалите все нежелательные записи, то есть те, у которых есть число, отличное от другого.

ОТВЕТ: Не используйте неявные раздельные соединения с запятой. Они были заменены явными объединениями более двадцати лет назад по уважительным причинам.

select wh_id, trlr_num, arrdte, invnum, supnum, 
from 
(
    select 
    ym.wh_id, ym.trlr_num, ym.arrdte, ri.invnum, ri.supnum, 
    row_number() over (partition by ri.invnum order by ym.arrdte desc) as rn 
    from rcvinv ri 
    join yms_ymr ym on ri.trknum = ym.trlr_num 
    where ym.trlr_cod = 'RCV' 
    and ym.wh_id <= 50 
    and ym.trlr_stat in ('C','CI','R','OR') 
    and ym.arrdte is not null 
) 
where rn = 1 
order by arrdte desc, trlr_num; 
+0

Спасибо Thorsten. Я попытался использовать запрос, но я все еще получаю много повторяющихся значений для trlr_num и invnum. Я пробовал использовать разные, но безрезультатно. Нужно еще что-то изменить? –

+0

Вы получаете дубликаты invnums? Я не понимаю, как это возможно. Я использую row_number per invnum, поэтому может быть только одна запись с номером 1 на invnum. –

+0

Вы все равно можете получить дубликаты trlr_nums, поскольку мы выбираем последнюю запись за invnum, и такие записи могут иметь одинаковый trlr_num. Если это нежелательно, вам нужно будет уточнить, что вы на самом деле хотите: одна строка за invnum? Одна строка на trlr_num? Или каждый invnum и каждый trlr_num, но как можно меньше записей? –

0

Это показывает, что главная проблема здесь заключается не в том, как писать запрос, а в том, что нужно писать. Прежде всего выражение «различные значения как столбца, так и строки» не имеет большого смысла. Я заметил, что вы показывали разные ПО с последним трейлером и соответственно отвечали на мой ответ. Но, очевидно, это не то, что вы действительно имели в виду.

Из ваших различных комментариев Я собираю это: вы хотите показать все строки, для которых не существует более позднего трейлера (trlr_num) с тем же PO (invnum) и более высоким поставщиком (supnum) для того же трейлера (trlr_num). Это означает два предложения NOT EXISTS. Если это на самом деле то, что вы хотите, то ваш запрос:

with myquery as 
(
    select ym.wh_id, ym.trlr_num, ym.arrdte, ri.invnum, ri.supnum 
    from rcvinv ri 
    join yms_ymr ym on ri.trknum = ym.trlr_num 
    where ym.trlr_cod = 'RCV' 
    and ym.wh_id <= 50 
    and ym.trlr_stat in ('C','CI','R','OR') 
    and ym.arrdte is not null 
) 
select * 
from myquery 
where not exists 
(
    select * 
    from myquery later_trailer 
    where later_trailer.invnum = myquery.invnum 
    and later_trailer.arrdte > myquery.arrdte 
) 
and not exists 
(
    select * 
    from myquery higher_vendor 
    where higher_vendor.trlr_num = myquery.trlr_num 
    and higher_vendor.supnum > myquery.supnum 
);