我得到了这张表:
CREATE TABLE Test_Table (
old_val VARCHAR2(3),
new_val VARCHAR2(3),
Updflag NUMBER,
WorkNo NUMBER );
这是在我的表中:
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('1',' 20',0,0);
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('2',' 20',0,0);
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('2',' 30',0,0);
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('3',' 30',0,0);
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('4',' 40',0,0);
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('4',' 40',0,0);
现在我的表看起来像这样:
Row Old_val New_val Updflag WorkNo
1 '1' ' 20' 0 0
2 '2' ' 20' 0 0
3 '2' ' 30' 0 0
4 '3' ' 30' 0 0
5 '4' ' 40' 0 0
6 '5' ' 40' 0 0
(如果new_val
列中的值相同,则它们在一起,同样转到old_val
)
所以在上面的例子中,第1-4行在一起,第5-6行是
目前我的存储过程中有一个光标:
SELECT t1.Old_val, t1.New_val, t1.updflag, t1.WorkNo
FROM Test_Table t1
WHERE t1.New_val =
(
SELECT t2.New_val
FROM Test_Table t2
WHERE t2.Updflag = 0
AND t2.Worknr = 0
AND ROWNUM = 1
)
输出是这样的:
Row Old_val New_val Updflag WorkNo
1 1 20 0 0
2 2 20 0 0
我的问题是,我不知道如何通过一个选择获得第1行到第4行。 (我有4个子查询的想法,但如果它的更多数据匹配在一起,这将不起作用)
你有没有人有想法?答案 0 :(得分:1)
您可以使用分析来定义连续行组:
SQL> SELECT old_val, new_val, updflag, workno,
2 SUM(gap) over(ORDER BY old_val, new_val) grp
3 FROM (SELECT t.*,
4 CASE
5 WHEN new_val = lag(new_val)
6 over(ORDER BY old_val, new_val)
7 OR old_val = lag(old_val)
8 over(ORDER BY old_val, new_val)
9 THEN
10 0
11 ELSE
12 1
13 END gap
14 FROM Test_Table t);
OLD_VAL NEW_VAL UPDFLAG WORKNO GRP
------- ------- ---------- ---------- ----------
1 20 0 0 1
2 20 0 0 1
2 30 0 0 1
3 30 0 0 1
4 40 0 0 2
4 40 0 0 2
内部SELECT构建一个“GAP”列,当前一行与前一行不在同一组时,该列等于1.
外部SELECT使用间隙列上的运行总计来获取组编号。
由于分析函数,您无法将FOR UPDATE子句直接添加到查询中。您可以直接查询基表:
SQL> WITH t_new AS (
2 SELECT t_rowid, old_val, new_val, updflag, workno,
3 SUM(gap) over(ORDER BY old_val, new_val) grp
4 FROM (SELECT t.*, t.rowid t_rowid,
5 CASE
6 WHEN new_val = lag(new_val)
7 over(ORDER BY old_val, new_val)
8 OR old_val = lag(old_val)
9 over(ORDER BY old_val, new_val)
10 THEN
11 0
12 ELSE
13 1
14 END gap
15 FROM test_table t)
16 )
17 SELECT *
18 FROM test_table
19 WHERE ROWID IN (SELECT t_rowid
20 FROM t_new
21 WHERE grp = (SELECT grp
22 FROM t_new t2
23 WHERE t2.new_val = ' 20'
24 AND t2.old_val = '1'))
25 FOR UPDATE;
OLD_VAL NEW_VAL UPDFLAG WORKNO
------- ------- ---------- ----------
1 20 0 0
2 20 0 0
2 30 0 0
3 30 0 0
答案 1 :(得分:0)
如果您想要的是返回的所有“与某些内容一起”的行,那么您的原始示例数据似乎不会提供不应返回的行。所以,让我们添加以下内容:
INSERT INTO Test_Table (old_val, new_val, Updflag , WorkNo) VALUES('6',' 50',0,0);
此行不应与任何内容一起使用,不应返回。鉴于此,我认为我们可以使用EXISTS来获得您想要的东西:
Select *
From Test_Table T1
Where Exists (
Select 1
From Test_Table T2
Where ( T2.old_val = T1.old_val Or T2.new_val = T1.new_val )
And ( T2.row <> T1.row )
)