我需要检索列和行的不同值。下面给出了当前设置中的oracle sql查询:
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)的重复输出已被删除。
简而言之,我想修改查询,以便我得到行和列的不同,如下面的输出。 请帮忙。感谢。
答案 0 :(得分:1)
您可以使用分析 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>
更新 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子句将被解析为临时表,因此您无需创建任何静态表。
答案 1 :(得分:1)
您的请求可以写成:获取每个invnum的最新记录。您可以通过按所需顺序对每个invnum(即ROW_NUMBER
)的行进行编号(即使用PARTITON BY invnum
),以使最新记录获得#1(ORDER BY ym.arrdte DESC
)。编号完成后,您将删除所有不需要的记录,即那些编号为1的记录。
BTW:不要再使用隐式逗号分隔联接。二十多年前,他们被明确的联合所取代,原因很充分。
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;
答案 2 :(得分:0)
它表明这里的主要问题不是如何编写查询,而是编写什么查询。首先,表达“列和行的不同值”没有多大意义。我注意到你是用最新的预告片显示不同的PO并相应地写了我的其他答案。但显然这不是你真正想到的。
根据您的不同评论,我收集到了这一点:您希望显示同一预告片(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
);