簡體   English   中英

Oracle 11g:如何在SQL查詢中選擇“額外”行

[英]Oracle 11g: How To Select 'Extra' Rows in SQL Query

使用Oracle 11g,並在工程文檔環境中工作,我需要選擇一個行集合,其中包括先前版本和多個文檔表的“額外”行。

具體來說,我們的數據庫僅記錄每個工程文檔的最新修訂。 我們需要為每個修訂和這些記錄的每一頁返回一行。

我們有這樣的數據:

DRAW_NUM        REV NUM_SHTS
LD-111-639-01   2   3

我們需要像這樣的數據:

DRAW_NUM        REV SHT
LD-111-639-01   1   1
LD-111-639-01   1   2
LD-111-639-01   1   3
LD-111-639-01   2   1
LD-111-639-01   2   2
LD-111-639-01   2   3

我最新的SQLPlus查詢嘗試使用一個外部表列出從0到Rev以及從0到Num_Shts的數字,並且代碼如下所示:

SELECT DISTINCT prefix || '-' || lpad(series,3,0) || '-' || lpad(base,3,0) || '-' || lpad(suffix,2,0) Draw_Num,
(select n from numbers where n >=0 and n <= md_draw.rev) Rv,
(select n from numbers where n >=0 and n <= md_draw.num_shts) Sht
FROM md_draw WHERE Dwg_Date <= TO_DATE('1-JUN-02')
ORDER BY Draw_Num, Rv, Sht
/

但是會產生以下錯誤:

ORA-01427:單行子查詢返回多個行

是否有捷徑可尋?

您的兩個子查詢將返回多行,您將需要使用某種聚合函數( Min()Max()等)來指定所需的單個項目:

SELECT DISTINCT prefix || '-' || lpad(series,3,0) || '-' || lpad(base,3,0) || '-' || lpad(suffix,2,0) Draw_Num,
(select Max(n) from numbers where n >=0 and n <= md_draw.rev) Rv,
(select Max(n) from numbers where n >=0 and n <= md_draw.num_shts) Sht
FROM md_draw WHERE Dwg_Date <= TO_DATE('1-JUN-02')
ORDER BY Draw_Num, Rv, Sht

或者,如果需要所有這些,則應使用JOIN而不是子查詢:

SELECT DISTINCT prefix || '-' || lpad(series,3,0) || '-' || lpad(base,3,0) || '-' || lpad(suffix,2,0) Draw_Num, 
       n1.n As Rv, n2.n As Shts
FROM md_draw 
JOIN numbers n1 
ON n1.n BETWEEN 0 AND md_draw.rev
JOIN numbers n2
ON n2.n BETWEEN 0 AND md_draw.num_shts
WHERE Dwg_Date <= TO_DATE('1-JUN-02')
ORDER BY Draw_Num, Rv, Sht

您可能需要調整最后一個查詢,我沒有時間通過​​sqlfiddle或其他任何方式運行它,但是它應該為您提供基本的操作思路。 僅觀察一下,我看不到revnum_shts與您的numbers表中的n有什么關系。

那是因為下面的子查詢產生了多於1行。 如果md_drawnumbers之間存在關系,則考慮進行JOIN

(select n from numbers where n >=0 and n <= md_draw.rev) Rv

Oracle安裝程序

CREATE TABLE table_name ( DRAW_NUM, REV, NUM_SHTS ) AS
SELECT 'LD-111-639-01', 2, 3 FROM DUAL UNION ALL
SELECT 'LD-111-639-02', 0, 2 FROM DUAL UNION ALL
SELECT 'LD-111-639-03', 7, 0 FROM DUAL UNION ALL
SELECT 'LD-111-639-04', 1, 2 FROM DUAL;

查詢-使用遞歸子查詢分解子句

WITH rsqfc ( draw_num, rev, num_shts, rv, sht ) AS (
  SELECT draw_num, rev, num_shts, 1, 1
  FROM   table_name
  WHERE  REV > 0 AND num_shts > 0
UNION ALL
  SELECT draw_num, rev, num_shts,
         CASE sht WHEN num_shts THEN rv+1 ELSE rv END,
         CASE sht WHEN num_shts THEN 1 ELSE sht+1 END
  FROM   rsqfc
  WHERE  rv < rev
  OR     sht < num_shts
)
SELECT draw_num, rv AS rev, sht
FROM   rsqfc
ORDER BY draw_num, rv, sht;

查詢-使用分層查詢

SELECT t.draw_num,
       r.COLUMN_VALUE AS rev,
       n.COLUMN_VALUE AS sht
FROM   table_name t,
       TABLE(
         CAST(
           MULTISET(
             SELECT LEVEL
             FROM   DUAL
             WHERE  t.REV > 0
             CONNECT BY LEVEL <= t.REV
           ) AS SYS.ODCINUMBERLIST
         )
       ) r,
       TABLE(
         CAST(
           MULTISET(
             SELECT LEVEL
             FROM   DUAL
             WHERE  t.NUM_SHTS > 0
             CONNECT BY LEVEL <= t.NUM_SHTS
           ) AS SYS.ODCINUMBERLIST
         )
       ) n;

輸出

DRAW_NUM             REV        SHT
------------- ---------- ----------
LD-111-639-01          1          1 
LD-111-639-01          1          2 
LD-111-639-01          1          3 
LD-111-639-01          2          1 
LD-111-639-01          2          2 
LD-111-639-01          2          3 
LD-111-639-04          1          1 
LD-111-639-04          1          2 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM