Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.94/33: Рейтинг темы: голосов - 33, средняя оценка - 4.94
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109

SQL запрос с условиями

24.09.2010, 12:49. Показов 7483. Ответов 80
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. У меня такой вопрос: нужно составить запрос SQL так что бы присутствовали операторы IF.

Если быть точнее, ситуация такая: нужно сформировать таблицу в которой изначально есть совпадения, но по ходу формирования нужно, их исключать при этом сумировать количество, типа, если уже есть запись, в поле Count (Количество) прибавить соответствующее значение...

что можете посоветовать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.09.2010, 12:49
Ответы с готовыми решениями:

Вывод 3 столбцов с условиями после выполнения SQL запроса
Помогите пожалуйста сделать запрос. with qqry do begin SQL.Clear; SQL.Add('SELECT SUM(PRICE) FROM OOC WHERE...

Динамический sql запрос с 4-мя независимыми условиями
Всем привет. Возникла следущая проблема-нужно составить динамический sql запрос, который может содержать до 4-х(включительно) независимых...

sql запрос для БазыДанных с условиями
Уваж Форумчане! Поправьте новичка! Пишу запрос для схемы БД! Дайте пару советов по корректировке! Выбрать все товары по стоимости ниже...

80
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 13:19
Студворк — интернет-сервис помощи студентам
DenProx, я попробовал - у меня последний вариант отрабатывает.
Вот этот:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
  ts.KEY AS stend_id,
  ts.name AS stend_name,
  td.KEY AS detail_id,
  td.name AS detail_name,
  SUM(td.count) AS sum_detail_count
FROM
  tblStend AS ts,
  tblBlock AS tb,
  tblDetail AS td
WHERE
  ts.KEY = :stend_id
  AND ts.KEY = tb.stend_id
  AND tb.KEY = td.block_id
GROUP BY
  ts.KEY,
  ts.name,
  td.KEY,
  td.name
Т. е. я открыл запрос, перешёл в режим SQL и ввёл текст этого запроса. Потом выполнил: запрос - открыть. Система запросила ввод параметров, я ввёл только один - stend_id = 41. В результате получил сведения по трём деталям. Кстати, в базе у двух разных деталей (разные ИД) одинаковое имя.
1
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
27.09.2010, 13:40  [ТС]
Цитата Сообщение от Mawrat Посмотреть сообщение
Кстати, в базе у двух разных деталей (разные ИД) одинаковое имя.
так и должно быть, просто разные болки мугут содержать в себе одинаковые детали.

Добавлено через 10 минут
Mawrat, кст. в результате должно быть две детали, в Count должно быть 8 у повторной детали

Добавлено через 8 минут
у меня кстати почему то при нажати "Выполнить" нужно вводить три параметра...
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 13:58
Цитата Сообщение от DenProx Посмотреть сообщение
так и должно быть, просто разные болки мугут содержать в себе одинаковые детали.
В таком случае, у одинаковых диталей должны быть одинаковые detail_id и различающиеся block_id. А мы сейчас в базе имеем - разные detail_id для деталей с одинаковыми именами.
Сейчас таблица tblDetail содержит такие данные:
detail_id block_id obosnach_name count
96 36 пкн61-н2-1-1-8 4
97 37 пкн61-н2-1-1-8 4
99 37 п2г3-2п4н переключатель 4
А должно быть так:
96 36 пкн61-н2-1-1-8 4
96 37 пкн61-н2-1-1-8 4
99 37 п2г3-2п4н переключатель 4
Т. е. деталь с detail_id = 96 должна присутствовать в блоке block_id = 36 и в блоке block_id = 37.
Вот тогда запрос будет правильно всё подсчитывать. Т. е. тогда запрос для детали detail_id = 96 выдаст количество: count = 8.
Цитата Сообщение от DenProx Посмотреть сообщение
у меня кстати почему то при нажати "Выполнить" нужно вводить три параметра...
У меня тоже запрашивает несколько параметров. Почему так происходит - не знаю. Я с Access не работал - не знаю особенностей в этой системе. Наверное где-то можно задать количество параметров...
---
Чтобы не запутаться с ИД деталей, можно создать отдельную таблицу - справочник деталей. В этой таблице сделать уникальный detail_id. В этом справочнике будет прописано наименование для каждой детали. А та таблица, которая сейчас назыается tblDeteil - её переделать в таблицу "отображения". Т. е. в ней уникальным ключом будет пара: (block_id, detail_id) и эта таблица уже не должна содержать наименований деталей - она только для связи между блоками и деталями. Это стандартный подход - различные объекты должны быть представлены отдльными таблицами (справочниками). Сложные связи задаются другими таблицами - таблицами "отображения". Здесь правда, можно оставить всё как есть, только надо не запутаться при этом с ИД деталей. Т. е. надо помнить, что одинаковые детали имеют всегда одинаквый ИД. И на имя детали не надо опираться.
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
27.09.2010, 14:02  [ТС]
Mawrat, по моему все в порядке...

вот схема данных... первое поле это не ID а ключевле поле - счетчик
Миниатюры
SQL запрос с условиями  
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 14:09
О, раз такая схема - это неправильно... В таблице tblDeteil уникальным ключом должна быть обязательно пара: (block_id, detail_id), а не отдельное поле detail_id.
---
На самом деле, как я писал в предыдущем посте, должна быть четвёртая таблица - справочник деталей - в ней должен быть ключ detail_id. При этом справочник деталей и справочник блоков должны ссылаться на таблицу отображения - т. е. на ту таблицу, которая сейчас называется tblDeteil. В таблице tblDeteil ключом должна быть пара: (block_id, deteil_id).
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
27.09.2010, 14:11  [ТС]
Mawrat, почему не правильно? Блок може быть как отдельное изделие, и информации о стенде в детали просто не откуда будет взяться...
Здесь все просто: Стенд состоит из блоков, Блоки состоят из деталей.
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 14:27
Цитата Сообщение от DenProx Посмотреть сообщение
Стенд состоит из блоков, Блоки состоят из деталей.
В этом случае, если по правилам делать, то должны быть такие таблицы:
Справочники:
tblStend, ИД: stend_id;
tblBlock, ИД: block_id;
tblDetail, ИД: detail_id;
Таблицы отображений (функциональные т. е.):
tblStBl, ИД: (stend_id, block_id);
tblBlDt, ИД: (block_id, detail_id).
---
Но сейчас мы имеем только один справочник в чистом виде - это tblStend. Остальные таблицы: tblBlock и tblDetail - это не справочники, а таблицы отображения или таблицы функциональной связи. Они сейчас и как справочники используются - что не правильно с точки зрения правил архитектурного строительства базы. Но в любом случае, они должны быть построены так:
таблица tblBlock, ИД: (stend_id, block_id);
таблица tblDetail, ИД: (block_id, detail_id).
Именно в этом случае будет реализована связь: Стенды - Блоки - Детали.
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
27.09.2010, 14:31  [ТС]
Mawrat, справочники есть, просто я вырезал их из примера.... что бы проще было)

Добавлено через 23 секунды
нужно сделать по тому что есть, то что мне нужно)))
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 14:45
В любом случае, касательно ключей в таблицах должно быть именно так:
tblStBl, ИД: (stend_id, block_id);
tblBlDt, ИД: (block_id, detail_id).
Только такой способ позволяет содержать варианты, когда разные стенды могут содержать один и тот же блок и разные блоки могут содержать одну и ту же деталь.
---
А... или тут detail_id - это не тип детали, а отдельная конкретная деталь? А тип детали задаётся её названием - detail_name? Аналогично для блоков - конкретный блок задаётся block_id, а тип блока - по block_name? И стенды - аналогично? Если так, тогда всё сложнее будет... Тогда лучше будет под тип стенда, блока, детали использовать отдельные ИД. Т. е. будем тогда иметь ИД типа стенда и ИД конкретного стенда.
---
Хотя, если не заморачиваться и исходить из того, что есть, тогда так. Если ИД детали - это отдельная конкретная деталь.И, аналогично, ИД блока - это конкретный блок, а его тип задаётся его наименованием. Также и для стендов. Тогда запрос будет таким:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT
  ts.KEY AS stend_id,
  ts.name AS stend_name,
  td.name AS detail_name,
  SUM(td.count) AS sum_detail_count
FROM
  tblStend AS ts,
  tblBlock AS tb,
  tblDetail AS td
WHERE
  ts.KEY = :stend_id
  AND ts.KEY = tb.stend_id
  AND tb.KEY = td.block_id
GROUP BY
  ts.KEY,
  ts.name,
  td.name
В этом запросе агрегация проводится по типу детали - т. е. по наименованию детали.
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
27.09.2010, 14:51  [ТС]
ИД - это номер детали из справочника, т.е. это отдельная конкретная деталь.

Добавлено через 2 минуты
и опять ошибка... ищет в моих документах td.mdb ... и не может найти)
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
27.09.2010, 14:54
Подправил:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT
  ts.KEY AS stend_id,
  ts.name AS stend_name,
  td.name AS detail_name,
  SUM(td.count) AS sum_detail_count
FROM
  tblStend AS ts,
  tblBlock AS tb,
  tblDetail AS td
WHERE
  ts.KEY = :stend_id
  AND ts.KEY = tb.stend_id
  AND tb.KEY = td.block_id
GROUP BY
  ts.KEY,
  ts.name,
  td.name
Я сейчас выполнил этот запрос - увидел не то, что ожидал. Только одна запись с количеством 12. Так не должно быть... Я думаю это Access так стрёмно работает... либо надо что-то там настраивать.
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
28.09.2010, 13:01  [ТС]
похоже, все таки придется вручную запихивать записи...

Добавлено через 22 часа 3 минуты
в процессе составления ручного ввода, дело дошло до первого вопроса, который здесь рассматривался. Возникла ошибка, в Ацесе работает без проблем, в Delphi не хочет... пишет "Ошибка в синтаксисе предложения FROM"

вот код:
Delphi
1
2
3
4
5
6
7
DM.QSostav2.Active := False;
DM.QSostav2.SQL.Add('SELECT SectionName,SortName, ObosnachName, Nujno, Price,'+
                   ' Summa, SUM(count) AS count_sum, SUM(sklad) AS sklad_sum');
DM.QSostav2.SQL.Add('FROM Sostav2');
DM.QSostav2.SQL.Add('GROUP BY Sostav2.SectionName, Sostav2.SortName,'+
                    ' Sostav2.ObosnachName');
DM.QSostav2.Active := True;
SQL
1
2
3
SELECT Sostav2.SectionName, Sostav2.SortName, Sostav2.ObosnachName, SUM(Sostav2.Count) AS count_sum, SUM(Sostav2.Sklad) AS sklad_sum
FROM Sostav2
GROUP BY Sostav2.SectionName, Sostav2.SortName, Sostav2.ObosnachName;
что может быть не так?
0
1263 / 706 / 62
Регистрация: 21.12.2009
Сообщений: 2,256
28.09.2010, 13:13
А у Вас DM.QSostav2.SQL чистый. Может нужно
Delphi
1
DM.QSostav2.SQL.Clear;
1
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
28.09.2010, 13:15
DenProx, ну вообще они не сильно-то и похожи, у вас в запросе из билдера гораздо больше полей указано в select, при этом их нет в разделе group by... а без этого никак, если вы используете агрегатные функции
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
28.09.2010, 13:27  [ТС]
SAMZ, Clear действительно забыл поставить...))

Lord_Voodoo, я по разному пробывал, просто на текущий момент, было так...

Clear поставил, запрос дополнил:
Delphi
1
2
3
4
5
6
7
8
9
DM.QSostav2.Active := False;
DM.QSostav2.SQL.Clear;
DM.QSostav2.SQL.Add('SELECT Sostav2.SectionName, Sostav2.SortName, Sostav2.ObosnachName,'+
                    ' Sostav2.Nujno, Sostav2.Price, Sostav2.Summa,'+
                    ' SUM(Sostav2.Count) AS count_sum, SUM(Sostav2.Sklad) AS sklad_sum');
DM.QSostav2.SQL.Add('FROM Sostav2');
DM.QSostav2.SQL.Add('GROUP BY Sostav2.SectionName, Sostav2.SortName,'+
                    ' Sostav2.ObosnachName, Sostav2.Nujno, Sostav2.Price, Sostav2.Summa);
DM.QSostav2.Active := True;
но возникает ошибка, якобы поле Count не найдено...
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
28.09.2010, 13:32
DenProx, а оно в этой таблице точно есть? а может и конфликтуют имена тоже как вариант
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
28.09.2010, 13:49  [ТС]
Lord_Voodoo, точно есть...

вот конечный вариант...
Delphi
1
2
3
4
5
6
7
8
9
DM.QSostav2.Active := False;
DM.QSostav2.SQL.Clear;
DM.QSostav2.SQL.Add('SELECT Sostav2.id, Sostav2.SectionName, Sostav2.SortName, Sostav2.ObosnachName,'+
                    ' Sostav2.Nujno, Sostav2.Price, Sostav2.Summa, Sostav2.Count, Sostav2.Sklad,'+
                    ' SUM(Sostav2.Count) AS count_sum, SUM(Sostav2.Sklad) AS sklad_sum');
DM.QSostav2.SQL.Add('FROM Sostav2');
DM.QSostav2.SQL.Add('GROUP BY Sostav2.id, Sostav2.SectionName, Sostav2.SortName,'+
                    ' Sostav2.ObosnachName, Sostav2.Nujno, Sostav2.Price, Sostav2.Summa, Count, Sklad ');
DM.QSostav2.Active := True;
ошибки нет, но и группировки нет...
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
28.09.2010, 13:59
DenProx, почему вы так решили, у вас такой набор полей для группировки, что сразу группировку и не увидешь
0
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
28.09.2010, 14:01  [ТС]
Lord_Voodoo, смысл группировки в том чтобы исключить повторяющиеся записи... а в полях Count и Sklad сумировать значения этих повторений... на 1-й или 2-й странице я описывал, эту ситуацию...
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
28.09.2010, 14:11
DenProx, вы знаете, вам аксесс не даст использовать агрегатные функции без группировки... и для исключения повторяющихся записей всегда был distinct... и чем больше данных вы укажите в выборке, тем мельче будут группы, как вы уже догадались...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.09.2010, 14:11

SQL запрос с несколькими не обязательными условиями
Добрый день, коллеги! Пытаюсь сделать выборку из базы данных с условиями. Условия указываются в нескольких Combobox (на текущий...

SQL запрос для поиска значений с 2-мя условиями
Задача: найти значение поля status по наибольшей дате(idate) для каждого (уникального) договора (id_dogovor) Таблица вида: ...

Запрос с условиями
Здравствуйте! Пишу админку для галереи. Всё работает...но хотелось бы сделать всё работало красиво :) В общем есть 2 таблица в базе, одна...

Запрос с условиями
Здравствуйте! Пишу админку для галереи. Всё работает...но хотелось бы сделать всё работало красиво В общем есть 2 таблица в базе, одна...

Запрос с противоположными условиями
Существует база с двумя таблицами один ко многим. Создаю запрос для выборки из главной таблицы записей по условию...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru