Oracle sql 不同的查询

Oracle sql distinct query

我需要检索列和行的不同值。当前设置中的 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; 

以上returns输出如下:

> 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)的重复输出已被删除。

简而言之,我想修改查询,以便在下面的输出中获得行和列的区别。 请帮忙。谢谢

您可以使用解析 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 子句 将解析为临时 table,因此您无需创建任何静态 table.

您的请求可以写成:给我每个invnum的最新记录。您可以通过按所需顺序对每个 invnum(即 PARTITON BY invnum)的行进行编号(即使用 ROW_NUMBER)来获得此信息,以便最新记录获得 #1(ORDER BY ym.arrdte DESC)。编号完成后,您将删除所有不需要的记录,即那些编号不是 1 的记录。

顺便说一句:不要再使用隐式逗号分隔连接。二十多年前,出于充分的理由,它们被显式连接所取代。

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; 

说明这里主要的问题不是怎么写query,而是写什么query。首先,表达式 "distinct values of both the column and row" 没有多大意义。我注意到你在展示最新预告片的不同采购订单,并相应地写下了我的其他答案。但显然这不是你真正想要的。

根据您的不同评论,我得出以下结论:您想要显示所有没有后续预告片 (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
);