戈登的回答另一種(可能是也可能不是更快)是對一個兩行假「表」的部分交叉連接,就像這樣:
WITH your_table AS (SELECT 1 ID, 999 paramcomp, 'a' colval FROM dual UNION ALL
SELECT 1 ID, 80 paramcomp, 'b' colval FROM dual UNION ALL
SELECT 2 ID, 999 paramcomp, 'c' colval FROM dual UNION ALL
SELECT 3 ID, 85 paramcomp, 'd' colval FROM dual UNION ALL
SELECT 4 ID, 999 paramcomp, 'e' colval FROM dual UNION ALL
SELECT 4 ID, 75 paramcomp, 'f' colval FROM dual UNION ALL
SELECT 4 ID, 70 paramcomp, 'g' colval FROM dual)
-- end of mimicking your table; see SQL below:
SELECT yt.ID,
yt.paramcomp,
case WHEN dummy.id = 1 THEN yt.colval
WHEN dummy.id = 2 THEN yt.paramcomp_999_colval
END colval
FROM (SELECT ID,
paramcomp,
colval,
MAX(CASE WHEN paramcomp = 999 THEN colval END) OVER (PARTITION BY ID) paramcomp_999_colval
FROM your_table) yt
INNER JOIN (SELECT 1 ID FROM dual UNION ALL
SELECT 2 ID FROM dual) dummy ON dummy.id = 1 -- ensures every yt row is returned
OR (dummy.id = 2
AND paramcomp_999_colval IS NOT NULL
AND yt.paramcomp != 999) -- returns an extra row if the 999 paramcomp row exists but the current row isn't 999
ORDER BY yt.ID, yt.paramcomp DESC, yt.colval;
ID PARAMCOMP COLVAL
---------- ---------- ------
1 999 a
1 80 b
1 80 a
2 999 c
3 85 d
4 999 e
4 75 e
4 75 f
4 70 g
4 70 e
這是假設有每個id只有一個999 paramcomp行(例如,存在(id,paramcomp)的唯一約束)。
你必須測試一下這個和Gordon的答案,看看哪個數據性能最高。
埃塔:這裏是戈登的回答的一個固定的版本供您使用比較:
select id, paramcomp, colval
from your_table
union all
select id, paramcomp, paramcomp_999_colval colval
from (select yt.*, MAX(CASE WHEN paramcomp = 999 THEN colval END) OVER (PARTITION BY ID) paramcomp_999_colval
from your_table yt
) t
where paramcomp_999_colval IS NOT NULL and paramcomp <> 999
ORDER BY ID, paramcomp DESC, colval;
ETA2:
如果您:使用虛表的詳細解釋想要複製表中的所有行,可以交叉連接到具有兩行的表/子查詢,如下所示:
SELECT *
FROM your_table yt
CROSS JOIN (SELECT 1 ID FROM dual UNION ALL
SELECT 2 ID FROM dual) dummy;
ID PARAMCOMP COLVAL ID
---------- ---------- ------ ----------
1 999 a 1
1 80 b 1
2 999 c 1
3 85 d 1
4 999 e 1
4 75 f 1
4 70 g 1
1 999 a 2
1 80 b 2
2 999 c 2
3 85 d 2
4 999 e 2
4 75 f 2
4 70 g 2
但是,您並不總是希望出現重複行,因此您需要執行一個有點選擇性的內部連接。我會在最初的答案中分解內連接,這樣你就可以看到它做得更好了。
首先,這裏的部分加入,以確保在your_table每一行返回:
SELECT *
FROM your_table yt
INNER JOIN (SELECT 1 ID FROM dual UNION ALL
SELECT 2 ID FROM dual) dummy ON dummy.id = 1;
ID PARAMCOMP COLVAL ID
---------- ---------- ------ ----------
1 999 a 1
1 80 b 1
2 999 c 1
3 85 d 1
4 999 e 1
4 75 f 1
4 70 g 1
其次,這裏的的加入,確保選擇性加入
SELECT *
FROM your_table yt
INNER JOIN (SELECT 1 ID FROM dual UNION ALL
SELECT 2 ID FROM dual) dummy ON dummy.id = 2
AND yt.paramcomp != 999;
ID PARAMCOMP COLVAL ID
---------- ---------- ------ ----------
1 80 b 2
3 85 d 2
4 75 f 2
4 70 g 2
你的一部分可以看到第二部分,我們仍然得到id = 3行,這是我們不想要的。因此,在上面的最終答案中,我發現了paramcomp = 999行的colval,並使用條件最大分析函數返回了所有行。然後,我將它添加到第二個連接條件部分,以僅返回具有999 colval的行(如果它們沒有值,則假定999行不存在)。這確實假設colval將始終存在於999行。
我不認爲您的示例數據遵循您指定的規則。如果是這樣,那麼'id = 1'將有兩行999。請澄清這個問題。 –
當你說你想「複製一列」你的意思是一排,對嗎?我沒有看到任何額外的列創建。然後:如果您基於現有的一行創建新行,但ParamComp值不同,那麼它甚至不是「重複」。在標題中:關係數據庫具有「行」而不是「記錄」。 – mathguy
@GordonLinoff對於一個ID,999是要比較的值,根據999個其他行的ColVal被複制 - (如果一個ID的ParamComp爲'999'且非999值)。 –