Oracle Query返回单行

时间:2019-11-21 13:25:42

标签: sql oracle

我需要编写一个查询来返回第五行作为输出,以及另外两列分别从第一行和第三行捕获时间作为一天中的时间和发货时间来获取输出,区别这些行的是最后一个状态列和下一个状态列。 / p>

下面是我的查询和输出。

 SELECT DISTINCT
         SLMCU AS "BUSINESSUNIT",
         SLDOCO AS "ORDERNO",
         SLDCTO AS "ORDERTYPE",
         SLAN8 AS "CUSTOMERNO",
         ABALPH AS "CUSTOMERNAME",
         SLLITM AS "ITEMNO",
         SLDSC1 AS "DESCRIPTION",
         SLDSC2 AS "DESCRIPTION2",
         SLLTTR AS "LAST STATUS",
         SLNXTR AS "NEXT STATUS",
         CASE SLTRDJ
            WHEN 0 THEN TO_DATE (TO_CHAR (1 + 1900000), 'YYYYDDD')
            ELSE TO_DATE (TO_CHAR (SLTRDJ + 1900000), 'YYYYDDD')
         END
            AS "ORDER DATE",
         CASE SLADDJ
            WHEN 0 THEN TO_DATE (TO_CHAR (1 + 1900000), 'YYYYDDD')
            ELSE TO_DATE (TO_CHAR (SLADDJ + 1900000), 'YYYYDDD')
         END
            AS "SHIPPED DATE",
         SLTDAY AS "TIME",
         SLUORG / 10000 AS "ORDER QUANTITY",
         SLSOQS / 10000 AS "SHIPPED QUANTITY"
     FROM PRODDTA.F42199 INNER JOIN PRODDTA.F0101 ON SLAN8 = ABAN8 WHERE SLDOCO = 19437443
  -- WHERE ((SLLTTR = 520 AND SLNXTR = 540) OR (SLLTTR = 620 AND SLNXTR = 582)) AND SLDOCO = 19437443
ORDER BY "LAST STATUS" ASC;

enter image description here

删除了一些列以提高可见性。 enter image description here

所需的输出

enter image description here

3 个答案:

答案 0 :(得分:3)

根据您的排序标准(NEXT_STATUS)为行提供递增的行号,然后使用解析函数查找第一行和第三行的值,然后过滤以仅返回第五行:

WITH your_query AS (
  -- paste your query here
)
SELECT *
FROM   (
  SELECT t.*,
         MAX( CASE WHEN rn = 1 THEN time END ) OVER () AS time_of_day,
         MAX( CASE WHEN rn = 3 THEN time END ) OVER () AS shipped_time
  FROM   (
    SELECT q.*,
           ROW_NUMBER() OVER ( ORDER BY next_status ) AS rn
    FROM   your_query q
  ) t
  WHERE rn IN ( 1, 3, 5 )
)
WHERE  rn = 5;

备用版本:

WITH your_query AS (
  -- paste your query here
)
SELECT *
FROM   (
  SELECT t.*,
         MAX( CASE WHEN ROWNUM = 1 THEN time END ) OVER () AS time_of_day,
         MAX( CASE WHEN ROWNUM = 3 THEN time END ) OVER () AS shipped_time,
         ROWNUM AS rn
  FROM   (
    SELECT *,
    FROM   your_query
    ORDER BY next_status
  ) t
  WHERE ROWNUM <= 5
)
WHERE  rn = 5;

更新多个ORDERNO

WITH your_query AS (
  -- paste your query here
)
SELECT *
FROM   (
  SELECT t.*,
         MAX( CASE WHEN rn = 1 THEN time END ) OVER ( PARTITION BY orderno ) AS time_of_day,
         MAX( CASE WHEN rn = 3 THEN time END ) OVER ( PARTITION BY orderno ) AS shipped_time
  FROM   (
    SELECT q.*,
           ROW_NUMBER() OVER ( PARTITION BY orderno ORDER BY next_status ) AS rn
    FROM   your_query q
  ) t
  WHERE rn IN ( 1, 3, 5 )
)
WHERE  rn = 5;

答案 1 :(得分:1)

这将使您获得第五行;

select * from (<<your_query>> where rownum<=5 order by rownum desc) x where rownum <= 1;

现在,按照您的要求执行以下操作(您可能需要稍微调整一下查询);

with row1 as (select * from (<<your_query>> where rownum<=5 order by rownum desc) x where rownum <= 1)
select (select time from (<<your_query>> where rownum<=3 order by rownum desc) y where rownum <= 1) as time,
select (select shippedtime from (<<your_query>> where rownum<=1 order by rownum desc)) as shippedtime,
BUSINESSUNIT,
ORDERNO,
ORDERTYPE,
CUSTOMERNO,
CUSTOMERNAME,
ITEMNO,
DESCRIPTION,
DESCRIPTION2,
"LAST STATUS",
"NEXT STATUS",
"ORDER DATE",
"ORDER QUANTITY",
"SHIPPED QUANTITY"
from
<<your_query>>
where 
 "NEXT STATUS" = (select "NEXT STATUS" from row1)
 AND "LAST STATUS" = (select "LAST STATUS" from row1);

用您在问题中输入的查询替换<<your_query>>,它应该可以工作。 另外,您可能必须在我的查询中添加位置和顺序,才能使查询正常工作。

答案 2 :(得分:1)

您可以使用nth_value分析功能。

首先获取所有具有唯一值的列,然后使用nth_value选择要在结果中显示该列的值,然后使用distinct,如下所示。

Select distinct
<all_columns except last_status, next_status, time, shipped_date and shipped_time>,
nth_value(last_status, 5) over (order by last_status) as last_status,
nth_value(next_status, 5) over (order by last_status) as next_status,
nth_value(time, 1) over (order by last_status) as time,
nth_value(shipped_date, 5) over (order by last_status) as shipped_date,
nth_value(shipped_time, 3) over (order by last_status) as shipped_time
From (your_query)

干杯!