遍历 table 的列值
Loop through column values of table
我是 PL-SQL 的新手。我有一个 table,其中包含数千条文件信息记录(摘录如下所示)。我需要比较 2 个文件 A 和 B,对于同一任务,检查 task_name 是否相同或不同.例如,在下面的 table 中,文件 A 任务 10 与文件 B 任务 10 具有相同的 task_name (xx)。而文件 A 任务 20 与文件 B 任务 20 具有不同的 task_name .我应该能够标记出这些差异和相似之处。我想在游标内使用游标来循环和比较这些值,但我不知道如何去做。我目前正在使用 Oracle 11。谢谢
File Task Task_name
A 10 xx
A 20 xy
A 30 xz
B 10 xx
B 20 xz
**编辑
感谢您的回复。我需要循环的原因是因为最后我需要显示结果
在以下格式的 clob 变量中。所以我需要在迭代中捕获任务编号和任务名称
在 clob 变量中显示
------文件比较------
不同Task_name
任务 20:文件 A Task_name xx 与文件 B Task_name xz
任务 30:文件 A Task_name xz 对比文件 B Task_name NULL
相同Task_name
任务 10:Task_namexx
您不需要使用 PL/SQL,而是使用 SQL 和 COUNT(..) OVER (..)
分析函数,通过使用 Task
和 Task_name
列分组 PARTITION BY
子句连同 CASE..WHEN
条件表达式就足够了,例如
SELECT f.*,
CASE WHEN COUNT(DISTINCT "File") OVER (PARTITION BY Task, Task_name) = 2 THEN
'Same'
ELSE CASE WHEN COUNT(DISTINCT "File") OVER (PARTITION BY Task) = 1 THEN
'Unique'
ELSE
'Different'
END
END AS flag
FROM files f
您也可以使用 operator EXISTS
。EXISTS 运算符与子查询一起使用以测试行是否存在。
尽管在您的问题中没有提及 A/B 内的重复项,您可以使用通用查询在 相同组或不同 /
中查找重复项
还要注意这个查询return在只在一个文件组内重复的情况下的正确结果(例如,只在A中) :
--using cte to set row's number
with cte as
(
select *, row_number()over (order by Task,TaskName)num from Table
)
select File,Task,TaskName,
case
--using t1.num<>t2.num because current row can refer to itself
when exists (select 1 from cte t1 where t1.Task=t2.Task and
t1.Taskname=t2.TaskName and t1.num<>t2.num)
then 'Duplicate'
else
'No Duplicate'
end as flag
from cte t2
如果在您的table中一个文件组中没有重复项,并且您只需要查找 A 和 B 文件组之间的差异,那么可以使用此查询:
select File,Task,TaskName,
case
when exists (select 1 from Table t1 where t1.Task=t2.Task and
t1.Taskname=t2.TaskName and t1.File<>t2.File)
then 'Duplicate'
else
'No Duplicate'
end as flag
from Table t2
您可以使用window function count
对文件group.But 中的Task、TaskName 进行计数,首先您需要删除每个组中的重复项,然后像在一个组中一样对值进行计数。
如果您需要比较 2 个文件 A 和 B,那么您可以尝试这个查询:
Select File, Task,TaskNane,case when countVal>1 then 'Duplicate' else 'No
Duplicate' and as flag
From
(
Select count(*)over (partition by file_gr, Task, TaskName) countVal
From
(
--add new accessorial column as if there's one group
Select *, case when File='B' then 'A' else 'A' end as file_gr
From
(
--remove duplicate within each group A and B
Select distinct File, Task, TaskName from Table
) X
) Y
) Z
with t (Files, Task, Task_name ) as
(
select 'A',10,'xx' from dual union all
select 'A',20,'xy' from dual union all
select 'A',30,'xz' from dual union all
select 'B',10,'xx' from dual union all
select 'B',20,'xz' from dual
)
select t1.*, nvl((select 'Y' from t t2 where t2.files <> t1.files and t2.task = t1.task and t2.task_name = t1.task_name),'N') as is_same
from t t1
order by 1, 2
输出:
您可以按任务汇总以获得差异:
select
task,
max(case when file = 'A' then task_name end) as task_file_a,
max(case when file = 'B' then task_name end) as task_file_b
from mytable
where file in ('A', 'B')
group by task
having count(*) <> 2 or count(distinct task_name) <> 1
order by task;
您可以在 PL/SQL 中使用它和 Cursor FOR LOOP
。这是草稿:
create or replace function get_diff return clob is
v_clob clob;
begin
for row in
(
select
task,
max(case when file = 'A' then task_name end) as task_file_a,
max(case when file = 'B' then task_name end) as task_file_b,
case when count(*) <> 2 or count(distinct task_name) <> 1
then 'diff'
else 'same'
end as diff_same
from mytable
where file in ('A', 'B')
group by task
order by diff_same, task
) loop
v_clob := v_clob + ...
end loop;
end;
您可以像这样访问行数据:'Task for file A is' || row.task_file_a
.
您必须检查相同/差异,或者您只需使用两个循环,一个用于差异,一个用于相等。
我是 PL-SQL 的新手。我有一个 table,其中包含数千条文件信息记录(摘录如下所示)。我需要比较 2 个文件 A 和 B,对于同一任务,检查 task_name 是否相同或不同.例如,在下面的 table 中,文件 A 任务 10 与文件 B 任务 10 具有相同的 task_name (xx)。而文件 A 任务 20 与文件 B 任务 20 具有不同的 task_name .我应该能够标记出这些差异和相似之处。我想在游标内使用游标来循环和比较这些值,但我不知道如何去做。我目前正在使用 Oracle 11。谢谢
File Task Task_name
A 10 xx
A 20 xy
A 30 xz
B 10 xx
B 20 xz
**编辑
感谢您的回复。我需要循环的原因是因为最后我需要显示结果 在以下格式的 clob 变量中。所以我需要在迭代中捕获任务编号和任务名称 在 clob 变量中显示
------文件比较------
不同Task_name
任务 20:文件 A Task_name xx 与文件 B Task_name xz
任务 30:文件 A Task_name xz 对比文件 B Task_name NULL
相同Task_name
任务 10:Task_namexx
您不需要使用 PL/SQL,而是使用 SQL 和 COUNT(..) OVER (..)
分析函数,通过使用 Task
和 Task_name
列分组 PARTITION BY
子句连同 CASE..WHEN
条件表达式就足够了,例如
SELECT f.*,
CASE WHEN COUNT(DISTINCT "File") OVER (PARTITION BY Task, Task_name) = 2 THEN
'Same'
ELSE CASE WHEN COUNT(DISTINCT "File") OVER (PARTITION BY Task) = 1 THEN
'Unique'
ELSE
'Different'
END
END AS flag
FROM files f
您也可以使用 operator EXISTS
。EXISTS 运算符与子查询一起使用以测试行是否存在。
尽管在您的问题中没有提及 A/B 内的重复项,您可以使用通用查询在 相同组或不同 /
中查找重复项还要注意这个查询return在只在一个文件组内重复的情况下的正确结果(例如,只在A中) :
--using cte to set row's number
with cte as
(
select *, row_number()over (order by Task,TaskName)num from Table
)
select File,Task,TaskName,
case
--using t1.num<>t2.num because current row can refer to itself
when exists (select 1 from cte t1 where t1.Task=t2.Task and
t1.Taskname=t2.TaskName and t1.num<>t2.num)
then 'Duplicate'
else
'No Duplicate'
end as flag
from cte t2
如果在您的table中一个文件组中没有重复项,并且您只需要查找 A 和 B 文件组之间的差异,那么可以使用此查询:
select File,Task,TaskName,
case
when exists (select 1 from Table t1 where t1.Task=t2.Task and
t1.Taskname=t2.TaskName and t1.File<>t2.File)
then 'Duplicate'
else
'No Duplicate'
end as flag
from Table t2
您可以使用window function count
对文件group.But 中的Task、TaskName 进行计数,首先您需要删除每个组中的重复项,然后像在一个组中一样对值进行计数。
如果您需要比较 2 个文件 A 和 B,那么您可以尝试这个查询:
Select File, Task,TaskNane,case when countVal>1 then 'Duplicate' else 'No
Duplicate' and as flag
From
(
Select count(*)over (partition by file_gr, Task, TaskName) countVal
From
(
--add new accessorial column as if there's one group
Select *, case when File='B' then 'A' else 'A' end as file_gr
From
(
--remove duplicate within each group A and B
Select distinct File, Task, TaskName from Table
) X
) Y
) Z
with t (Files, Task, Task_name ) as
(
select 'A',10,'xx' from dual union all
select 'A',20,'xy' from dual union all
select 'A',30,'xz' from dual union all
select 'B',10,'xx' from dual union all
select 'B',20,'xz' from dual
)
select t1.*, nvl((select 'Y' from t t2 where t2.files <> t1.files and t2.task = t1.task and t2.task_name = t1.task_name),'N') as is_same
from t t1
order by 1, 2
输出:
您可以按任务汇总以获得差异:
select
task,
max(case when file = 'A' then task_name end) as task_file_a,
max(case when file = 'B' then task_name end) as task_file_b
from mytable
where file in ('A', 'B')
group by task
having count(*) <> 2 or count(distinct task_name) <> 1
order by task;
您可以在 PL/SQL 中使用它和 Cursor FOR LOOP
。这是草稿:
create or replace function get_diff return clob is
v_clob clob;
begin
for row in
(
select
task,
max(case when file = 'A' then task_name end) as task_file_a,
max(case when file = 'B' then task_name end) as task_file_b,
case when count(*) <> 2 or count(distinct task_name) <> 1
then 'diff'
else 'same'
end as diff_same
from mytable
where file in ('A', 'B')
group by task
order by diff_same, task
) loop
v_clob := v_clob + ...
end loop;
end;
您可以像这样访问行数据:'Task for file A is' || row.task_file_a
.
您必须检查相同/差异,或者您只需使用两个循环,一个用于差异,一个用于相等。