Помогите с запросов

Ngels
Дата: 19.11.2009 13:35:31
Уважаемые!

Третий день не могу побороть запрос, помогите, пожалуйста.

Есть две таблицы:

ЛИЦО (как вмдно, сохраняю в ней и физиков и юриков)
Column NameData TypePrimary Key
ЛИЦО_КОДNUMBER1
ЮЛ_ИМЯ_КРАТКОVARCHAR2(4000)
ЮЛ_ИМЯ_ПОЛНОЕVARCHAR2(4000)
ЮЛ_ИМЯ_АНГЛVARCHAR2(4000)
ЮЛ_ИННVARCHAR2(10)
ЮЛ_КППVARCHAR2(9)
ЮЛ_ОГРНVARCHAR2(13)
ЮЛ_ЕГРЮЛ_ДАТАDATE
ЮЛ_ЕГРЮЛ_ОРГАНVARCHAR2(4000)
ЮЛ_ОКПОVARCHAR2(10)
БАНК_БИКVARCHAR2(9)
БАНК_КОРСЧЕТVARCHAR2(20)
БАНК_SWIFTVARCHAR2(20)
ФЛ_ИННVARCHAR2(12)
ФЛ_ДРDATE
ФЛ_МРVARCHAR2(4000)
ФЛ_ПОЛVARCHAR2(2)
ФЛ_ФАМИЛИЯVARCHAR2(4000)
ФЛ_ИМЯVARCHAR2(4000)
ФЛ_ОТЧЕСТВОVARCHAR2(4000)
ФЛ_ПАС_СЕРИЯVARCHAR2(4)
ФЛ_ПАС_НОМЕРVARCHAR2(6)
ФЛ_ПАС_ДАТАDATE
ФЛ_ПАС_ОРГАНVARCHAR2(4000)
ФЛ_ПАС_КПVARCHAR2(4000)
ИП_ОГРНИПVARCHAR2(15)
ИП_ЕГРИП_ДАТАDATE
ИП_ЕГРИП_ОРГАНVARCHAR2(4000)
ПРИМЕЧАНИЕVARCHAR2(4000)
ЮЛ_ОПФVARCHAR2(20)
ЛИЦО_ТИПVARCHAR2(4)
ЮЛ_ОКАТОVARCHAR2(4000)


и тиблица ГД (Генеральный дироектор)
Column NameData TypePrimary Key
ОБЩЕСТВОNUMBER1
ГДNUMBER2
ГД_СDATE3
ГД_ПОDATE
ПРИМЕЧАНИЕVARCHAR2(4000)
ГД_ОГРАНИЧЕНИЕVARCHAR2(4000)


Необходимо вывести результатом список всех имеющихся компаний и их Генеральных.
Проблема в том, что в таблице ГД может содержаться несколько Генеральных для одной компании, которые отличаются полем ГД_С. Естественно, хочется выбрать для компании долько свежего Директора, т.е. того, у которого ГД_С самая поздняя.

Нашел на форуме решение этой проблемы в виде
...where
"ГД"."ГД_С" IN (select max("ГД_С") from "ГД" tt where "ГД"."ОБЩЕСТВО" = tt."ОБЩЕСТВО")

Но в связи с этим условием возникла другая проблема.
Дело в том, что в таблице ГД представлены Директора не для всех компаний.
Таким образом из результата моего запроса при включении вешеописанной строки исключились компании, где Генеральный не определен.

ЧТО ЖЕ ДЕЛАТЬ, КАК ЖЕ БЫТЬ ???



Вот сам исходный запрос, над которым мозг ломаю:

select 
 case 
 when instr("ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ",'"',1)>0 
 then "ЛИЦО"."ЮЛ_ОПФ" || ' "' || "ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ"
 else "ЛИЦО"."ЮЛ_ОПФ" || ' "' || "ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ" || '"'
 end as "НАИМЕНОВАНИЕ",

	 "ЛИЦО"."ЮЛ_ИНН" as "ИНН",
	 "ЛИЦО"."ЮЛ_КПП" as "КПП",
	 "ЛИЦО"."ЮЛ_ОГРН" as "ОГРН",
	 "ЛИЦО"."ЮЛ_ЕГРЮЛ_ДАТА" as "ОГРН-ДАТА",
	 "ЛИЦО_1"."ФЛ_ФАМИЛИЯ" || ' ' || SUBSTR("ЛИЦО_1"."ФЛ_ИМЯ",1,1) || '.' || SUBSTR("ЛИЦО_1"."ФЛ_ОТЧЕСТВО",1,1) || '.' as "ГД",
	 "ГД"."ГД_С" as "ВСТУПИЛ",
	 "ГД"."ГД_ПО" as "ПРЕКРАЩАЕТ",
	 "ГД"."ГД_ОГРАНИЧЕНИЕ" as "ОГРАНИЧЕНИЯ"
 
 from	 "ЛИЦО" "ЛИЦО_1",
	 "ГД" "ГД",
	 "ЛИЦО" "ЛИЦО",
         "ЛИЦО_ГРУППА" 

where    "ЛИЦО"."ЛИЦО_КОД"="ГД"."ОБЩЕСТВО"(+)
  and	 "ГД"."ГД"="ЛИЦО_1"."ЛИЦО_КОД"(+)
  and 	 "ЛИЦО"."ЛИЦО_ТИП" ='ЮЛ'
  and    "ГД"."ГД_С" IN (select max("ГД_С") from "ГД" tt where "ГД"."ОБЩЕСТВО" = tt."ОБЩЕСТВО")

order by "ГРУППА","НАИМЕНОВАНИЕ"
suPPLer
Дата: 19.11.2009 13:45:34
Ngels,

x = nvl((select max(...) ...), x)

А вообще - STFF keep dense_rank.
Ngels
Дата: 19.11.2009 13:55:24
suPPLer,

Вот если так написать, не работает все равно почему-то:

where
"ГД"."ГД_С" = nvl((select max("ГД_С") from "ГД" tt where "ГД"."ОБЩЕСТВО" = tt."ОБЩЕСТВО"),"ГД"."ГД_С")
Ngels
Дата: 19.11.2009 15:19:18
Все найденные на форуме примеры не либо предполагают все одну таблицу (без join), либо не предполагают существование null даты.

Помогите, кто-нибудь, пожалуйста.
Andrey.L
Дата: 19.11.2009 15:26:36
Ngels,

and turunc(sysdate) between   "ГД"."ГД_С"(+) and "ГД"."ГД_ПО"(+)
Babe_Vampire
Дата: 19.11.2009 15:43:09
and ("ГД"."ГД_С" = nvl((select max("ГД_С") from "ГД" tt where "ГД"."ОБЩЕСТВО" = tt."ОБЩЕСТВО"),"ГД"."ГД_С") OR ("ГД"."ГД_С" IS NULL))
----
Oracle 11.1.0.7 - 64bit - SLES10
Ngels
Дата: 19.11.2009 15:45:27
УРААА!!!

Вот так работает (с nvl(rn,1)=1):

select
         "ЛИЦО_ГРУППА"."ГРУППА",	 
 case 
 when instr("ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ",'"',1)>0 
 then "ЛИЦО"."ЮЛ_ОПФ" || ' "' || "ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ"
 else "ЛИЦО"."ЮЛ_ОПФ" || ' "' || "ЛИЦО"."ЮЛ_ИМЯ_ПОЛНОЕ" || '"'
 end as "НАИМЕНОВАНИЕ",

	 "ЛИЦО"."ЮЛ_ИНН" as "ИНН",
	 "ЛИЦО"."ЮЛ_КПП" as "КПП",
	 "ЛИЦО"."ЮЛ_ОГРН" as "ОГРН",
	 "ЛИЦО"."ЮЛ_ЕГРЮЛ_ДАТА" as "ОГРН-ДАТА",
	 "ЛИЦО_1"."ФЛ_ФАМИЛИЯ" || ' ' || SUBSTR("ЛИЦО_1"."ФЛ_ИМЯ",1,1) || '.' || SUBSTR("ЛИЦО_1"."ФЛ_ОТЧЕСТВО",1,1) || '.' as "ГД",
	 "ГД"."ГД_С" as "ВСТУПИЛ",
	 "ГД"."ГД_ПО" as "ПРЕКРАЩАЕТ",
	 "ГД"."ГД_ОГРАНИЧЕНИЕ" as "ОГРАНИЧЕНИЯ"
 
 from	 "ЛИЦО" "ЛИЦО_1",
	 (select "ГД".*, row_number() over(partition by "ГД"."ОБЩЕСТВО" order by "ГД"."ГД_С" desc) as rn from "ГД") "ГД",
	 "ЛИЦО" "ЛИЦО",
         "ЛИЦО_ГРУППА" 

where    "ЛИЦО"."ЛИЦО_КОД"="ГД"."ОБЩЕСТВО"(+)
  and	 "ГД"."ГД"="ЛИЦО_1"."ЛИЦО_КОД"(+)
  and 	 "ЛИЦО"."ЛИЦО_ТИП"='ЮЛ'
  and    "ЛИЦО"."ЛИЦО_КОД"="ЛИЦО_ГРУППА"."ЛИЦО"(+)
  and    nvl(rn,1)=1

order by "ГРУППА","НАИМЕНОВАНИЕ"


Спасибо всем большое!
Ngels
Дата: 19.11.2009 15:51:18
Babe_Vampire
and ("ГД"."ГД_С" = nvl((select max("ГД_С") from "ГД" tt where "ГД"."ОБЩЕСТВО" = tt."ОБЩЕСТВО"),"ГД"."ГД_С") OR ("ГД"."ГД_С" IS NULL))
----
Oracle 11.1.0.7 - 64bit - SLES10


И ТАК ТОЖЕ !)))

Спасибо большое! Я то все пыталься OR IS NULL отдельным условием поставить, а он на то, что "с inner join OR не используют" ругался.