Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

одной строкой

1 view
Skip to first unread message

Serg Stepanov

unread,
May 3, 2006, 3:47:53 AM5/3/06
to
Hi All,

Можно ли эти два запроса объединить в один?
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)

Igor Korolyov

unread,
May 3, 2006, 6:40:17 AM5/3/06
to
Hi Serg!
You wrote to All on Wed, 03 May 2006 10:47:53 +0600:

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

Serg Stepanov

unread,
May 3, 2006, 10:46:50 PM5/3/06
to
Спасибо Игорь, об отсутствии кривизны в базе остаётся только мечтать, да и до
создания базы со всеми её триггерами, связями между таблицами, продуманной
структурой и нормализацией довольно далеко, здесь простые таблицы, которые
создаются 'с лёта'. Постепенно отрабатывается и шлифуется структура,
выясняются связи с другими таблицами и т.д., но, чтоб это было делать быстрее,
нужна максимальная гибкость и отсутствие жёстких правил баз.
К сожалению, я так и не научился задавать правильных вопросов, хотя и читал
предложенную вами статью ('Как правильно задавать вопросы', на втором пункте я
зевнул и ушёл с этого сайта), поэтому все предложенные вами способы(как и мой
тоже, я его тоже проверил на практике) не подходят. Например есть две таблицы:

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, которая встречается дважды, даст неправильный
результат..

Vladimir Maksimov

unread,
May 4, 2006, 12:46:20 PM5/4/06
to
Thu May 04 2006 06:46, Serg Stepanov wrote to Igor Korolyov:

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Е_ "присоединение"

Serg Stepanov

unread,
May 5, 2006, 3:15:15 AM5/5/06
to
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?

В итоге хотелось бы видеть следующее
kod naim k
1 11111 12
3 3333(код не уникальный) 36
4 код не найден 4

Vladimir Maksimov

unread,
May 6, 2006, 1:08:30 PM5/6/06
to
Fri May 05 2006 11:15, Serg Stepanov wrote to Vladimir Maksimov:

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

Serg Stepanov

unread,
May 9, 2006, 9:38:41 PM5/9/06
to
Спасибо..., правда один нюанс остался GROUP BY 1,2, а не GROUP BY
tab1.kod,naim...это стиль или это сделано специально, и результаты будут
разниться...

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

Vladimir Maksimov

unread,
May 11, 2006, 1:17:13 PM5/11/06
to
Wed May 10 2006 05:38, Serg Stepanov wrote to Vladimir Maksimov:

SS> From: "Serg Stepanov" <mi...@postkk.krasnoyarsk.ru>

SS> Спасибо..., правда один нюанс остался GROUP BY 1,2, а не GROUP BY
SS> tab1.kod,naim...это стиль или это сделано специально, и результаты будут
SS> разниться...

Специально, разумеется. Когда используются цифры - это дополнительно
подчеркивает тот факт, что для группировки используются выражения в опции
SELECT, а не собственно поля таблицы.

Serg Stepanov

unread,
May 11, 2006, 8:57:15 PM5/11/06
to
Спасибо, правда есть ещё один мелкий вопрос, типа есть условие
WHERE tab1.kod <> 0 в твоём выпажении, а есть ли способы(или функции), которые
бы отделяли пустую запись от записи не заполненого кода, т.е. если код=0, но в
записи имеются какие-либо значения, то запись попадала бы в выборку, а если
полностью пустая запись, то в выборку бы не попадала..

Vladimir Maksimov

unread,
May 12, 2006, 12:53:30 PM5/12/06
to
Fri May 12 2006 04:57, Serg Stepanov wrote to Vladimir Maksimov:

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

Serg Stepanov

unread,
May 14, 2006, 10:06:04 PM5/14/06
to

SS>> Спасибо, правда есть ещё один мелкий вопрос, типа есть условие
SS>> WHERE tab1.kod <> 0 в твоём выпажении, а есть ли способы(или функции),
SS>> которые бы отделяли пустую запись от записи не заполненого кода, т.е.
SS>> если код=0, но в записи имеются какие-либо значения, то запись попадала
SS>> бы в выборку, а если полностью пустая запись, то в выборку бы не
SS>> попадала..

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

Igor Korolyov

unread,
May 16, 2006, 6:47:46 PM5/16/06
to
Hi Serg!

You wrote to Vladimir Maksimov on Mon, 15 May 2006 05:06:04 +0600:

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


0 new messages