C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Помогите написать SQL запрос!!!!!
Sweta
  Отправлено: 02.04.2004, 09:39


Не зарегистрирован







Здраствуйте... у меня возник следующий вопрос...
У меня есть 2 таблицы — Приход(Код изделия, Наименование, №Накладной, Количество, Цена, Поставщик), Расход(Код изделия, Наименование, №Накладной, Количество, Потребитель). Надо создать таблицу Остаток(Код изделия, Наименование, Количество).
Приход.Наименование = Расход.Наименование.
Как вывести для каждой записи поля Количество(разность между полем Количество таблицы Приход и полем Количество таблицы Расход) таблицы Остаток соответствующие записи поля Наименование?
Gedeon
Отправлено: 02.04.2004, 11:15


Ветеран

Группа: Модератор
Сообщений: 1742



CODE

SELECT Приход.Код изделия,
 Приход.Наименование,
 Приход.Количество — Расход.Количество AS Разность -- или количество
WHERE
 Приход.Наименование = Расход.Наименование

Коды изделий, я так понимаю тоже совпадают. Неплохо бы нормализовать таблицы.

Отредактировано Gedeon — 02/04/2004, 12:20
olegenty
Отправлено: 03.04.2004, 07:29


Ветеран

Группа: Модератор
Сообщений: 2412



И вместо WHERE накропать LEFT OUTER JOIN, иначе в остаток не попадут изделия, по которым нет записей в таблице Расход.
Bubble
Отправлено: 19.04.2004, 00:52


Ученик-кочегар

Группа: Участник
Сообщений: 7



А зачем вообще делать таблицы вида приход-расход?

Не проще ли сделать такую структуру:

Изделия (код, наименование, описание, бла-бла)

Движения(код, количество). расход хранить с минусом. Можно и с плюсом, но надо будет вводить поле тип документа (приход/расход), что в примере ясности не прибавит.

Тогда список количеств будет
select Изделия.код, Изделия.Наименование, sum(Движения.количество) where изделия.код=Движения.код group by Изделия.код.

За совсем точность построения запроса не ручаюсь, но смысл передает.

Плюсы:
-- Быстрее любых joinов,
-- Нет проблем с непоказом полей.
olegenty
Отправлено: 19.04.2004, 06:34


Ветеран

Группа: Модератор
Сообщений: 2412



ну и всё равно нужен всё тот же LEFT OUTER JOIN по коду изделия, иначе в результат не попадут те изделия кодификатора, у которых нет связанных записей в Движениях...
Bubble
Отправлено: 20.04.2004, 23:04


Ученик-кочегар

Группа: Участник
Сообщений: 7



Ну во-первых, если изделия не попадут, то по ним наличие 0. Это может устроить: показываем наличие того, что есть.
Во-вторых, если делать более сложную схему, то для наличия можно использовать не запрос, но таблицу наличия, которую периодически апдейтить практически таким же запросом. Для простоты функцию апдейта такой таблицы я бы сделал как очистку; вставку имеющихся наличий; вставку нулевых позиций. Это конечно небыстро, но имеет свои плюсы: не нужно каждый раз когда нужны данные, делать большой запрос с Join, проще поддерживать целостность, добавляя/удаляя наличие в таблице наличия при изменении документов, а функцию пересчета использовать в целях проверки/корректирования.

olegenty
Отправлено: 21.04.2004, 09:20


Ветеран

Группа: Модератор
Сообщений: 2412



2Babble — вот уж этого-то я и не стал бы делать как раз. зачем плодить таблицы, неопредмеченные реальной сущьностью предметной области, когда можно написать грамотный JOIN. +, зачем плодить искусственную избыточность данных, когда всё тот же грамотный JOIN решит все проблемы.

заметь, он [джоин] большой только для разработчика. а уж если разработчик в курсе структуры БД, не пофиг ли ему, какая будет степень вложенности/объединения запроса?

налицо тема — разработка структуры БД.
Gedeon
Отправлено: 21.04.2004, 10:26


Ветеран

Группа: Модератор
Сообщений: 1742



Ну вы тут блин полемику устроили, человек запрос попросил, а вы что, вот для SQL SERVER, если надо для другого напишите для чего:
CODE

SELECT   Приход.Код изделия,
             Приход.Наименование,
             Приход.Количество — ISNULL(Расход.Количество,0) AS Разность -- или количество
FROM   Приход LEFT OUTER JOIN Расход ON Приход.Наименование = Расход.Наименование
olegenty
Отправлено: 21.04.2004, 11:15


Ветеран

Группа: Модератор
Сообщений: 2412



для Interbase/Firebird/Yaffil:
CODE

SELECT
   Приход.Код изделия,
   Приход.Наименование,
   Приход.Количество ПКол,
   Расход.Количество РКол
FROM  
   Приход LEFT OUTER JOIN Расход
   ON Приход.Наименование = Расход.Наименование


разность рассчитать на клиенте, иначе она будет NULL, где Расход.Количество отсутствует (т.е. NULL)

либо написать UDF, аналогичную ISNULL, и подставить, либо сделать вышеупомянутое действие в хранимой процедуре посредством реализации цикла
FOR SELECT...
DO BEGIN
вычитание;
SUSPEND
END
Guest
Отправлено: 21.04.2004, 22:35


Не зарегистрирован







QUOTE (olegenty @ 21/04/2004, 10:22)
заметь, он [джоин] большой только для разработчика. а уж если разработчик в курсе структуры БД, не пофиг ли ему, какая будет степень вложенности/объединения запроса?


Ладно, ладно... Убедил smile.gif Конечно, можно так сделать.
Мне просто Join для наличия не нравится в силу того, что запрос этот будет гоняться постоянно. Вычислительный ресурс, так скать, сожрет...
** Bubble
Отправлено: 21.04.2004, 22:37


Не зарегистрирован







QUOTE (olegenty @ 21/04/2004, 12:17)
разность рассчитать на клиенте, иначе она будет NULL, где Расход.Количество отсутствует (т.е. NULL)

либо написать UDF, аналогичную ISNULL, и подставить, либо сделать вышеупомянутое действие в хранимой процедуре посредством реализации цикла
FOR SELECT...
DO BEGIN
вычитание;
SUSPEND
END

Бедная девушка smile.gif)
Интересно, она за мыслью-то еще следит?
olegenty
Отправлено: 22.04.2004, 06:57


Ветеран

Группа: Модератор
Сообщений: 2412



2Guest
QUOTE

Вычислительный ресурс, так скать, сожрет...


оптимизацию запроса проведи, индексов нарисуй рациональное количество по нужным полям, и всё будет оч. быстро происходить, с минимумом реальных обращений к винту...

да, и если база серьёзная... у меня на работе на 8-и сказёвых винтах 10-й раид собран... и 6 гиг оперативки. вот и прикинь, как это летает, если на оптимизацию глаза не закрываются.

2Bubble
она не уточнила, какой СУБД и какими средствами пользуется. может вообще Paradox + BDE.
Deem
Отправлено: 04.05.2004, 12:13


Мастер участка

Группа: Участник
Сообщений: 327



Зашугали человека. cool.gif
Я думаю, тут Fox ли Access. И, возможно, контрольная работа. Так что JOIN, сдается мне, явно лишний.

Про страусинные трупы я вобще молчу. smile.gif

Отредактировано Deem — 04/05/2004, 13:18
Gedeon
Отправлено: 05.05.2004, 09:38


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Deem @ 04/05/2004, 13:15)
Зашугали человека. cool.gif
Я думаю, тут Fox ли Access. И, возможно, контрольная работа. Так что JOIN, сдается мне, явно лишний.

Про страусинные трупы я вобще молчу. smile.gif

А что в MS ACCESS разве оператор join отменили?
Deem
Отправлено: 05.05.2004, 11:08


Мастер участка

Группа: Участник
Сообщений: 327



Да нет. Уровень учитывать надо.

Вернуться в Работа с базами данных в C++Builder