在Oracle中选择包含一条记录的表

时间:2018-03-16 05:45:16

标签: sql oracle

Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range
With ActiveDocument.Tables(1)
  Set Rng = .Range
  With .Range
    With .Find
      .ClearFormatting
      .Replacement.ClearFormatting
      .Text = ", ([A-Z])"
      .Replacement.Text = ""
      .Forward = True
      .Wrap = wdFindStop
      .Format = False
      .MatchWildcards = True
      .Execute
    End With
    Do While .Find.Found
      If .InRange(Rng) Then
        .Case = wdLowerCase
      Else
        Exit Do
      End If
      .Collapse wdCollapseEnd
      .Find.Execute
    Loop
  End With
End With
Application.ScreenUpdating = True
End Sub

我想在表格中找到一条记录。

3 个答案:

答案 0 :(得分:1)

如果您的查询提供了所需的数据,但您只想查看count等于1的结果,则可以像这样包装查询:

select * from (
  select table_name, 
  to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select 
  count(*) c from '||owner||'.'||table_name)),'/ROWSET/ROW/C')) as count 
  from all_tables
) where count = 1

答案 1 :(得分:1)

只有在应用过滤谓词时,查询才会崩溃。这可能是某些查询重写优化中的错误。如果您将查询包装在具有materialize提示的块中,则似乎可以绕过此行为。

with workaround as(
    select /*+ materialize */ 
           owner
          ,table_name
          ,to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from ' || owner || '.' || table_name || ' where rownum <= 2')),'/ROWSET/ROW/C')) as row_count 
      from all_tables
     where owner = '<your-schema>'
)
select owner, table_name, row_count
  from workaround
 where row_count = 1;

我还发现了一些改善此查询性能的潜力。如果您只想要具有一个记录的表,则实际上不需要计算表中的每个记录。如果添加谓词rownum <= 2,Oracle会在找到两条记录后立即停止扫描。所以计数将是:

  • 0,意思是空表
  • 1,意思是一个记录
  • 2,意思是超过1条记录

编辑以显示优化的工作原理:

-- Creating tables 
create table t0(c number);
create table t1(c number);
create table t2(c number);
create table t3(c number);

insert into t1 values(1);


insert into t2 values(1);
insert into t2 values(2);


insert into t3 values(1);
insert into t3 values(2);
insert into t3 values(3);

commit;

SQL:

/*
|| Without rownum you can filter on any rowcount you want
*/
select *
  from (select 'T0' as t, count(*) as row_count from t0 union all
        select 'T1' as t, count(*) as row_count from t1 union all
        select 'T2' as t, count(*) as row_count from t2 union all
        select 'T3' as t, count(*) as row_count from t3
       )
  where row_count = 1 -- Return tables having exactly 1 record.
  ;

/*
|| With rownum <= 1 Oracle will stop counting after it found one row.
|| So the rowcount will be either 0 or 1.
||  row_count = 0 means that the table is empty
||  row_count = 1 means that the table is NOT empty.
||
|| The Rownum predicate prevents us from knowing if there are 2,3,4 or 5 million records.
*/
select *
  from (select 'T0' as t, count(*) as row_count from t0 where rownum <= 1 union all
        select 'T1' as t, count(*) as row_count from t1 where rownum <= 1 union all
        select 'T2' as t, count(*) as row_count from t2 where rownum <= 1 union all
        select 'T3' as t, count(*) as row_count from t3 where rownum <= 1 
       )
  where row_count = 1 -- Return tables having at least one record
;  


/*
|| With rownum <= 2 Oracle will stop counting after it found two rows.
|| So the rowcount will be either 0, 1 or 2.
||  row_count = 0 means that the table is empty
||  row_count = 1 means that the table has exactly 1 record
||  row_count = 2 means that the table has more than 1 record
|| 
|| The Rownum predicate prevents us from knowing if there are exactly two records, or 3,4,5 etcetera
*/
select *
  from (select 'T0' as t, count(*) as row_count from t0 where rownum <= 2 union all
        select 'T1' as t, count(*) as row_count from t1 where rownum <= 2 union all
        select 'T2' as t, count(*) as row_count from t2 where rownum <= 2 union all
        select 'T3' as t, count(*) as row_count from t3 where rownum <= 2 
       )
  where row_count = 1 -- Return tables having exactly one record
  ;

答案 2 :(得分:0)

SELECT * FROM 
(
  SELECT table_name, 
  TO_NUMBER(EXTRACTVALUE(XMLTYPE(dbms_xmlgen.getxml('select count(*) c from '||OWNER||'.'||table_name)),'/ROWSET/ROW/C')) AS cnt 
  FROM all_tables
  ) 
WHERE cnt = 1;

SELECT * FROM 
(
  SELECT table_name, 
  TO_NUMBER(EXTRACTVALUE(XMLTYPE(dbms_xmlgen.getxml('select count(*) c from '||OWNER||'.'||table_name)),'/ROWSET/ROW/C')) AS cnt 
  FROM all_tables
  ) slct
GROUP BY slct.table_name
HAVING slct.cnt = 1;