Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 372

/ вопрос открыт /

Здравствуйте, уважаемые эксперты!
Есть две таблицы Таб1 иТаб2. У Таб1 поле "Приход", у Таб2 поля "Наличие"и "Факт". Как осуществить с помощью SQL запроса суммирование полей "Приход" и "Наличие" и отобразить результат в поле "Факт"?

timkit Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: timkit (статус: Посетитель)
Вопрос отправлен: 6 ноября 2009, 05:59
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 19; последнее сообщение — 10 ноября 2009, 12:27; участников в обсуждении: 2.
Егор

Егор (статус: 10-ый класс), 7 ноября 2009, 23:45 [#1]:

не совсем корректно спроектирована база
или я чего-то не так понял :)

подробнее бы. расписать бы немножко содержимое обеих таблиц.
типа, таблица Таб1:
id  Приход  Дата
 1   154     12.10.09
 2   200     13.10.09
...
таблица Таб2:
id  Наличие  Факт
 1   574     ???
 2   0       ???
...
если это примерно так, то, в общем случае, провести суммирование невозможно, поскольку непонятно, какую строку с какой суммировать (первую из первой таблицы + первая из второй или восьмая из первой + 10-я из второй)
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 05:35 [#2]:

Да, таблицы имеют именно такую структуру. Придется наверно переносить поле "Факт" в Таб1
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 05:48 [#3]:

По-хорошему, в Таб1 нужно переносить не Факт, а Наличие. а поле Факт вообще убрать - вычислять его при запросах, потому что само наличие поля Факт говорит об избыточности (есть данные, которые мы можем спокойно вычислить, а мы их храним), чего в реляционных базах данных стараются всеми избежать.


если же нужно оставить две таблицы (тогда поясните, зачем), то ситуацию тоже можно решить, но вот с суммированием строк будет заморочка.
всё дело в том, что в реляционных базах данных нет понятия "первая строка", "вторая строка", "n-я строка" или "последняя строка". поэтому в общем случае невозможно определить какую строчку от какой нужно вычитать. а что, если количество строк в одной таблице не совпадает с количество строк в другой?

НО! если в таблицах есть id и он один и тот же для Таб1 и Таб2, то тут уже можно что-то сделать.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 06:28 [#4]:

Для большей наглядности представляю структуру обоих таблиц:

Поля Таб1 - ID, Num, Material, Limit, Ostatok, Fakt
Поля Таб2 - ID, Num, Material, Prixod, Data, Instancer

При занесении данных в Таб1 поле Num (int) заполняется инкрементом т.е. при каждом "INSERT" происходит Num:=CLientDataset.Datasource.DataSet.RecordCount+1, таже заполняюся поля Material,Ostatok, Limit. Одновременно в таблицу Таб2 в поле Num вставляется запись со значением "1" (чтобы идентифицировать запись как соответсвующую записи из Таб1), в поле Material - материал, как в Таб1, Data и т.д.
При заполнении Таб2 поле Num аналогично заполняется инкрементом, но заполняется только поле Instancer,Prixod,Data.
Теперь при всем этих действиях (Заполненных полях Ostatok из Таб1 и Prix из Таб2, должно произойти суммарование всех записей поля Prix и значения из Ostatok).
Каряво, не спорю.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 06:56 [#5]:

УЖАСНО!
сведите обе таблицы в одну!
уберите поле Num нафиг - оно не нужно - зачем вам тогда поле id? вот пусть id и выполняет функции Num

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

ещё раз пишу:
1. обе таблицы свести в одну
2. убрать поле Num, а вместо него использовать ID
3. убрать поле Fakt, вычислять его при каждом обращении к базе

либо опишите, почему была выбрана такая структура и обоснуйте её
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 07:00 [#6]:

или я чего-то не понял?
вы уж опишите задачу полнее - что дано, что надо сделать, а то я так чувствую, что база изначально была спроектирована неверно, нет чёткого понимания, что нужно (и как) хранить в базе.

соответственно ищется ответ не на тот вопрос

таблица 1 для чего? что в ней должно храниться? данные по материалу? или данные по приходу?
таблица 2 для чего? в ней хранятся данные по расходу?

и по именам - называть таблицы "Таб1" и "Таб2" - это... мягко говоря, некорректно. такое именование не даёт никакого представления о том, что хранится в таблицах
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 07:29 [#7]:

Поле ID в данном случае - это поле которое в свою чередь является идентификатором для ссылки на другую таблицу - "Объекты", поэтому оно и присутствует.
Егор, если Вам не трудно прочтите следующее, может Вы предложите лучшую структуру или действительно свести все в одну таблицу.
Суть программы следующая:
Имеется дерево со списком предприятий у каждого предприятия свой дочерний узел - изделие. Каждое изделие имеет свой уникальный ID. В соответствии с этим ID в Таблицу "Материалы" заносятся данные.
Например:

ID Num Материал Остаток,кг Лимит, кг Факт, кг
-----------------------------------------------------
1 1 Труба 32 100 1000 800
1 2 Лист 140 500 340
1 3 Швеллер 500 100 100

В таблицу "Материал заменитель"
заносим теже ID и Num для идентификации среди других объектов и материалов соответственно. Таблица "Материал заменитель" содержит обязательно первую запись со строкой из Таблицы "Материалы" т.е. изначальный материал, а потом добавляются материалы заменители, если невозможно купить исходный материал. Поле ID_self - внутренний счетчик

ID Num Id_Self Материал Заменитель Приход,кг
------------------------------------------------
1 1 1 Труба 32 - 400
1 1 2 - Труба 36 700


В таблицу "Материал заменитель" я заношу приход материала, а в поле "Факт" я хотел отображать сумму того, что есть на складе т.е. значение из поля "Остаток" и значение из поля "Приход". Если заменитель присутствует то в сумму пойдет значение поля "Приход" именн для заменителя. Вот и все.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 08:59 [#8]:

мда, задачка...
т.е., я так понял, на складе есть материалы разных предприятий. также можно менять материалы (т.е. имеются данные по тому, какое изделие каким можно менять)
так?

кхм...

тогда я бы спроектировал по-другому. выделил бы таблицу "материалы" и вынес туда все-все материалы:
id   firm_id  material
----------------------
  1      1    Труба 32
  2      1    Лист
  3      1    Швеллер
  4      1    Труба 36  <--- перенёс из заменителей!
...
id - собственный номер материала
firm_id - номер предприятия

затем сделал бы таблицу "материалы-заменители", в которой описал бы, как можно менять материалы:
id_base    id_replace
---------------------
  1         4         <----- т.е. материал с id=1 (Труба 32) можем заменить материалом с id=4 (Труба 36)
...

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

кстати, а поле "лимит" - оно зачем?

ps просьба - таблицы оформляйте с помощью тегов {{ code }} {{ /code }} чтобы структура их была понятнее :)
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 09:26 [#9]:

Вообще эти две таблицы только часть программы. Суть ее заключается в следующем:
Как я уже писал, есть список объектов (Заказчиков) и входящих в него изделий, каждое изделие в свою очередь состоит из отдельных деталей, но детали не обозначаются, а обозначаются материалы, из которых они сделаны. В силу некоторых причин (отсутствие у поставщика или его удаленность) материал необходимо заменить аналогом (что и предполагалось делать во 2-ой таблице). Причем не факт, что замена произойдет один раз. Самое главное в программе - строгий учет (с привязкой к конкретной дате).
Почему я не сделал все в одной таблице? Потому как хранить все в одной куче показалось мне не совсем удобным, да и запросы слишком громоздкие получаться. Я решил сделать отношение таблиц по принципу "один ко многим".
Так то все нормально работает, но единственное, что вызвало затруднения, это вычисляемое поле "Факт"(фактическая масса материала в наличии). Кстати в поле "Лимит" заносятся данные о конечном, необходимом количестве материалов на изготовление.
Сама таблица "Материалы" тоже предполагает редактирование (не всегда человек может ввести правильные данные), но при изменении материала в таблице "Материалы" соответствующая запись должна измениться и в таблице "Замена материалов".
Ну вот в принципе и вся суть этой части программы.

P.S. Очень много хлопот доставило то, что БД работает удаленно, и клиентов несколько.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 12:17 [#10]:

что-то я запутался :)
а что в поле факт надо хранить?

а если заменителей несколько, как тогда вычислять? или заменителей не может быть несколько - всегда только один или ни одного?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 12:25 [#11]:

>> См. выше. В таблицу "Материал заменитель" я заношу приход материала, а в поле "Факт" я хотел отображать сумму того, что есть на складе т.е. значение из поля "Остаток" + значение из поля "Приход". Если заменитель присутствует то в сумму пойдет значение поля "Приход" именно для заменителя.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 13:03 [#12]:

а заменитель один?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 13:06 [#13]:

Не обязательно, может быть и несколько. Вообще редко возникают ситуации, что больше одного, но все же такую возможность включить нужно.
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 13:21 [#14]:

а тогда как быть? что в факт заносить?

и очень хорошо бы пример привести - записи в первой таблице, записи во второй, что должно быть в поле факт.
а то я так толком и не понял, если честно
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 13:36 [#15]:

Если заменитель присутствует то в сумму (т.е. в поле "Факт") пойдет значение поля "Приход" именно для заменителя (если их несколько то значение берется для последнего по дате заменителя).
Егор

Егор (статус: 10-ый класс), 9 ноября 2009, 13:47 [#16]:

тэкс... т.е. нам ещё одно поле вводить надо - время занесения записи. так получается?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 9 ноября 2009, 19:46 [#17]:

Добавлять не надо, оно уже есть.
Егор

Егор (статус: 10-ый класс), 10 ноября 2009, 10:01 [#18]:

тогда я вижу только один способ - программно заполнять это поле, т.е. читаем из таблицы материалов-заменителей нужную запись, а затем вычисляем нужное значение для поля факт
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
timkit

timkit (статус: Посетитель), 10 ноября 2009, 12:27 [#19]:

Спабо большое Егор за содействие!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 12:00
Выполнено за 0.04 сек.