Vanilla SQL с коррелированным подзапросом работает в T-SQL, не работает в PL / SQL - PullRequest
2 голосов
/ 16 февраля 2010

Я хотел бы использовать по существу один и тот же запрос как в T-SQL (SQL Server 2000/2005), так и в PL / SQL (Oracle 10g). Хотя это и не тривиально, но это достаточно ванильный код, но он работает в SQL Server, но не работает в Oracle. Моя цель состоит в том, чтобы сгенерировать количество строк для каждой уникальной комбинации прописных / строчных букв определенного поля, исключая любые значения полей, если существует только одна такая комбинация. Этот пример выходных данных, например, указывает на то, что маркер «два слова» появляется в четырех различных комбинациях верхнего / нижнего регистра, причем наиболее распространенным вариантом является версия всего верхнего регистра (121 таких строк).

  <i>alias</i>      <i>rows affected</i>
  phrase           25
  Phrase            3
  Two words        12
  Two Words         9
  TWO words         3
  TWO WORDS       121

Напоминаем, что SQL Server по умолчанию не учитывает регистр, поэтому предложение COLLATE позволяет мне работать с ним с учетом регистра. С другой стороны, Oracle не нуждается в массаже, так как он чувствителен к регистру.

Этот запрос отлично работает в T-SQL:

select
    description COLLATE SQL_Latin1_General_CP1_CS_AS as alias,
    count(*) as "Rows Affected"
from dbo.svcs t1 (nolock) 
where (
    select count(upper(alias)) as "Variation Count"
    from
    ( -- list of unique spellings for each alias
        select
            description COLLATE SQL_Latin1_General_CP1_CS_AS as alias,
            count(*) as count
        from dbo.svcs (nolock)
        where description = t1.description
        group by description COLLATE SQL_Latin1_General_CP1_CS_AS 
    ) combos
    group by upper(alias)
    having count(upper(alias)) > 1
) > 1
group by description COLLATE SQL_Latin1_General_CP1_CS_AS
order by description COLLATE SQL_Latin1_General_CP1_CS_AS

Этот запрос не выполняется в Oracle; он не распознает внешнюю ссылку, жалуясь, что использует «неверный идентификатор»:

select alias, count(*) as "Rows Affected"
from dev1.svcs t1
where (
    select count(upper(alias)) as "Variation Count"
    from
    ( -- list of unique spellings for each alias
        select alias, count(*) as count
        from dev1.svcs
        where upper(alias) = upper(t1.alias)     -- <<<<< Does not like outer reference to 't1.alias' here
        group by alias
    ) combos
    group by upper(alias)
    having count(upper(alias)) > 1
) > 1
group by alias
order by alias

Так есть ли обходной путь для Oracle PL / SQL?

2010.02.16 Обновление

После тестирования моего полного набора данных я принял ответ Гэри. Он исключил коррелированный подзапрос, чтобы получить более компактное решение, и это здорово, но мне все еще любопытно, почему попытка коррелированного подзапроса не удалась, если у кого-то возникли мысли по этому поводу ...

1 Ответ

2 голосов
/ 16 февраля 2010

Я думаю, вы можете сойти с рук

select alias, upper(alias), count(*) cnt_alias
from svcs m
where upper(alias) in
    (select upper(alias) up_a
    from svcs
    group by upper(alias)
    having count(distinct alias) > 1) 
group by alias
order by upper(alias), count(*) desc, alias;

Проверено с:

create table svcs (id number, alias varchar2(10));

insert into svcs select level, 'phrase' from dual connect by level <= 25;
insert into svcs select level, 'Phrase' from dual connect by level <= 3;
insert into svcs select level, 'Two words' from dual connect by level <= 12;
insert into svcs select level, 'Two Words' from dual connect by level <= 9;
insert into svcs select level, 'TWO words' from dual connect by level <= 3;
insert into svcs select level, 'TWO WORDS' from dual connect by level <= 121;
insert into svcs select level, 'Only' from dual connect by level <= 121;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...