Можно ли эти два запроса объединить в один?
SELECT SUM(k) as k,kod FROM table1 GROUP BY kod INTO CURSOR qqq
SELECT qqq.k, qqq.kod, table2.naim FROM qqq LEFT OUTER JOIN kod ON
qqq.kod=table2.kod
(vfp9)
SS> Можно ли эти два запроса объединить в один?
SS> SELECT SUM(k) as k,kod FROM table1 GROUP BY kod INTO CURSOR qqq
SS> SELECT qqq.k, qqq.kod, table2.naim FROM qqq LEFT OUTER JOIN kod ON
SS> qqq.kod=table2.kod
SS> (vfp9)
В лоб: Можно - просто разместить первый в части FROM второго (без опции INTO
CURSOR конечно). Первый запрос бери в скобки, за скобками пиши qqq - это
будет его локальный алиас (видимый внутри самого запроса).
SELECT qqq.k, ;
qqq.kod, ;
table2.naim ;
FROM (SELECT SUM(k) as k, ;
kod ;
FROM table1 ;
GROUP BY kod) qqq ;
LEFT OUTER JOIN table2 ;
ON qqq.kod=table2.kod
Если подумать: А что тебе собственно нужно то? Ты тут намутил с таблицами
table1, table2 и kod так что сам чёрт ногу сломит. предположим что ты просто
описАлся, и реально у тебя есть "рабочая" таблица table1 (ID I PK, k B(0),
kod I) и справочник table2 (kod I PK, naim C(200)). Через PK показаны
первичные ключи, причём для первой таблицы (где мы проводим суммирование)
наличие поля ID для данной задачи не обязательно - но в общем и целом
конечно в таблице должен быть PK потому он и показан в структуре :)
Тогда для получения "сумм с названиями" достаточно такого запроса:
SELECT SUM(table1.k) sum_k, ;
table1.kod, ;
table2.naim ;
FROM table1 LEFT OUTER JOIN table2 ;
ON table2.kod = table1.kod ;
GROUP BY table1.kod, table2.naim
Или такого:
SELECT SUM(table1.k) sum_k, ;
table1.kod, ;
MAX(table2.naim) naim ;
FROM table1 LEFT OUTER JOIN table2 ;
ON table2.kod = table1.kod ;
GROUP BY table1.kod
Кроме того этот запрос ориентирован на ситуацию "неполноты справочника" -
т.е. когда в table1 есть коды которых нет в table2 (что мягко говоря
показывает на ущербность/кривизну базы). Если тебе реально нужно было
получить обратную картину - т.е. чтобы были записи для ВСЕХ элементов
справочника независимо от того есть по ним суммы или нет - тогда вместо LEFT
нужен будет RIGHT JOIN, а так-же kod нужно будет брать не из table1, а из
table2.
--
WBR, Igor
table1 table2
kod k kod naim
1 1 1 1111
3 3 2 22222
(тут просто пустая запись) 3 33333
4 4 3 44444
(тут тоже пустая запись)
1 11
3 33
Т.е. допускается вероятность не уникальности справочника, и при всех запросах
получаем результат
kod naim k
.NULL. 0
1 11111 12
3 3333 36
3 44444 36
4 .NULL. 4
Мне действительно нужно левое объединение, т.е. все записи table1, и прицепить
к кодам наименование(или первое попавшееся или максимальное или т.д.),вместо
.Null. или пустая строка или "код не найден", пустые записи хотелось бы
исключить, а также я буду подводить итог по столбцу 'k'(когда буду сбрасывать
отчёт в Exel), и сумма 36, которая встречается дважды, даст неправильный
результат..
SS> From: "Serg Stepanov" <mi...@postkk.krasnoyarsk.ru>
SS> Hапример есть две таблицы:
SS> table1 table2
SS> kod k kod naim
SS> 1 1 1 1111
SS> 3 3 2 22222
SS> (тут просто пустая запись) 3 33333
SS> 4 4 3 44444
SS> (тут тоже пустая запись)
SS> 1 11
SS> 3 33
SS> Т.е. допускается вероятность не уникальности справочника, и при всех
SS> запросах получаем результат
SS> kod naim k
SS> .NULL. 0
SS> 1 11111 12
SS> 3 3333 36
SS> 3 44444 36
SS> 4 .NULL. 4
SS> ...и сумма 36, которая встречается
SS> дважды, даст неправильный результат..
Если я правильно понял, то приведенные результат - неправильный. Тогда напиши,
что _должно_ получится в итоговой выборке по указанным условиям. Как должна
обрабатываться неоднозначность по коду 3?
PS: Hадеюсь, понимаешь, что LEFT JOIN это _HЕ_ "присоединение"
SS>> ...и сумма 36, которая встречается
SS>> дважды, даст неправильный результат..
VM> Если я правильно понял, то приведенные результат - неправильный. Тогда
VM> напиши, что _должно_ получится в итоговой выборке по указанным условиям.
VM> Как должна обрабатываться неоднозначность по коду 3?
В итоге хотелось бы видеть следующее
kod naim k
1 11111 12
3 3333(код не уникальный) 36
4 код не найден 4
SS> From: "Serg Stepanov" <mi...@postkk.krasnoyarsk.ru>
SS>>> kod naim k
SS>>> .NULL. 0
SS>>> 1 11111 12
SS>>> 3 3333 36
SS>>> 3 44444 36
SS>>> 4 .NULL. 4
SS>>> ...и сумма 36, которая встречается
SS>>> дважды, даст неправильный результат..
VM>> Если я правильно понял, то приведенные результат - неправильный. Тогда
VM>> напиши, что _должно_ получится в итоговой выборке по указанным условиям.
VM>> Как должна обрабатываться неоднозначность по коду 3?
SS> В итоге хотелось бы видеть следующее
SS> kod naim k
SS> 1 11111 12
SS> 3 3333(код не уникальный) 36
SS> 4 код не найден 4
SELECT ;
tab1.kod, ;
PADR(NVL(temp2.naim,"код не найден"),30) as naim, ;
SUM(tab1.k) as sumK ;
FROM tab1 ;
LEFT JOIN ;
(select ;
tab2.kod, ;
MAX(tab2.naim) as naim ;
FROM tab2 ;
GROUP BY tab2.kod) temp2 ON temp2.kod=tab1.kod ;
WHERE tab1.kod <> 0 ;
GROUP BY 1,2
SS>> В итоге хотелось бы видеть следующее
SS>> kod naim k
SS>> 1 11111 12
SS>> 3 3333(код не уникальный) 36
SS>> 4 код не найден 4
VM> SELECT ;
VM> tab1.kod, ;
VM> PADR(NVL(temp2.naim,"код не найден"),30) as naim, ;
VM> SUM(tab1.k) as sumK ;
VM> FROM tab1 ;
VM> LEFT JOIN ;
VM> (select ;
VM> tab2.kod, ;
VM> MAX(tab2.naim) as naim ;
VM> FROM tab2 ;
VM> GROUP BY tab2.kod) temp2 ON temp2.kod=tab1.kod ;
VM> WHERE tab1.kod <> 0 ;
VM> GROUP BY 1,2
SS> From: "Serg Stepanov" <mi...@postkk.krasnoyarsk.ru>
SS> Спасибо..., правда один нюанс остался GROUP BY 1,2, а не GROUP BY
SS> tab1.kod,naim...это стиль или это сделано специально, и результаты будут
SS> разниться...
Специально, разумеется. Когда используются цифры - это дополнительно
подчеркивает тот факт, что для группировки используются выражения в опции
SELECT, а не собственно поля таблицы.
SS> From: "Serg Stepanov" <mi...@postkk.krasnoyarsk.ru>
SS> Спасибо, правда есть ещё один мелкий вопрос, типа есть условие
SS> WHERE tab1.kod <> 0 в твоём выпажении, а есть ли способы(или функции),
SS> которые бы отделяли пустую запись от записи не заполненого кода, т.е.
SS> если код=0, но в записи имеются какие-либо значения, то запись попадала
SS> бы в выборку, а если полностью пустая запись, то в выборку бы не
SS> попадала..
Hу, так добавь проверку содержимого других полей
VM>> SELECT ;
VM>> tab1.kod, ;
VM>> PADR(NVL(temp2.naim,"код не найден"),30) as naim, ;
VM>> SUM(tab1.k) as sumK ;
VM>> FROM tab1 ;
VM>> LEFT JOIN ;
VM>> (select ;
VM>> tab2.kod, ;
VM>> MAX(tab2.naim) as naim ;
VM>> FROM tab2 ;
VM>> GROUP BY tab2.kod) temp2 ON temp2.kod=tab1.kod ;
VM>> WHERE tab1.kod <> 0 ;
OR NOT EMPTY(tab1.f1) OR NOT EMPTY(tab1.f2) OR ... ;
VM>> GROUP BY 1,2
VM> Hу, так добавь проверку содержимого других полей
VM>>> SELECT ;
VM>>> tab1.kod, ;
VM>>> PADR(NVL(temp2.naim,"код не найден"),30) as naim, ;
VM>>> SUM(tab1.k) as sumK ;
VM>>> FROM tab1 ;
VM>>> LEFT JOIN ;
VM>>> (select ;
VM>>> tab2.kod, ;
VM>>> MAX(tab2.naim) as naim ;
VM>>> FROM tab2 ;
VM>>> GROUP BY tab2.kod) temp2 ON temp2.kod=tab1.kod ;
VM>>> WHERE tab1.kod <> 0 ;
VM> OR NOT EMPTY(tab1.f1) OR NOT EMPTY(tab1.f2) OR ... ;
^^^
Скорей всего "AND", но я понял..., просто спрашивал если полей будет 250, не
будешь же всех их перечислять, вот и поинтересовался...может есть что-нибудь
типа EMPTY(BLANK)...
VM>>> GROUP BY 1,2
VM>> OR NOT EMPTY(tab1.f1) OR NOT EMPTY(tab1.f2) OR ... ;
SS> ^^^
SS> Скорей всего "AND"
Ты спрашивал "в записи имеются какие-либо значения" - если использовать
AND - то семантика запроса будет "если в записи не пусты ВСЕ перечисленные
поля" - что есть конечно совсем другое...
SS> просто спрашивал если полей будет 250, не будешь же
SS> всех их перечислять
Будешь. Если у тебя таблица кривая (иначе назвать таблицу в которой имеют
место описанные тобой пакости никак нельзя) - то кто ж тебе виноват :)
Напиши программу так, чтобы там НЕ возникало ни пустых записей, ни записей с
кодом 0.
SS> вот и поинтересовался...может есть что-нибудь типа EMPTY(BLANK)...
Типа чего? Как ты себе представляешь одно условие описывающее ВСЮ запись?
Это может быть только выражение. Причём выражение может быть и не с кучей
мелких "OR ! EMPTY()" - но суть его от этого не меняется.
--
WBR, Igor