Помогите с запросом и перегрузкой результатов запроса

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Помогите с запросом и перегрузкой результатов запроса

Сообщение Al Prad » 07.12.2007 (Пт) 14:15

Добрый день!

Имеется 2 вопроса:

1. есть таблица dbf, подключил ее к Adodc. В ней есть поля (информация от заводских весов): Дата (напр. 07.12.2007), время ( напр. 13,02), масса отвеса весов (напр. 732,3). Завод работает в 2 смены ( 8.00-20.00 и 20.00-8.00). Помогите построить запрос, чтобы в результате получить суммы отвесов за каждую смену, отсортированные по дате. Например:
7.12.07 - ПерваяСмена - Сумма=62382
7.12.07 - ВтораяСмена - Сумма=2561
8.12.07 - ПерваяСмена......... и т.д.

2. Затем необходимо из этого запроса сгрузить данные в таблицу файла mdb, у которой есть поля Дата, Смена, Сумма. Не знаю, как это сделать. Есть идея, что в цикле, перебирая Дату и Смену, но чувствую, что это глупость и есть какой-то быстрый метод, о котором я пока не знаю.

Спасибо за ответы, извините за наивные вопросы :)

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 11.12.2007 (Вт) 14:13

Ага. Все понятно. Придется делать через жопу.

gjghjc
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 659
Зарегистрирован: 13.10.2002 (Вс) 8:28
Откуда: БАЛАКЛАВА!!

Сообщение gjghjc » 11.12.2007 (Вт) 15:26

Ну я бы например ввел еще одно поле куда бы вставлял номер смены
1 или 2
Потом
Код: Выделить всё
SELECT Sum(table1.Massa) AS [Sum-Massa], table1.Date_, table1.Smena
FROM table1
GROUP BY table1.Date_, table1.Smena;


Если нельзя ввести еще одно поле со сменой тогда так

Код: Выделить всё
SELECT Sum(table1.Massa) AS [Sum-Massa], table1.Date_
FROM table1
GROUP BY table1.Date_, ( (time_ BETWEEN #08:00:00# AND #19:59:00#) AND  (time_ BETWEEN #20:00:00# AND #07:59:00#));


Вот глянь вложение версия Access - XP.
Вложения
test.zip
(9.69 Кб) Скачиваний: 98
Утро добрым не бывает!

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Сообщение kibernetics » 11.12.2007 (Вт) 15:28

1. Примерно так:
Код: Выделить всё
SELECT Date, IIF(Time>20:00,"1 Смена", "2 Смена") As Smena, Massa
FROM table

2. смотри в сторону SELECT INTO и INSERT

gjghjc
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 659
Зарегистрирован: 13.10.2002 (Вс) 8:28
Откуда: БАЛАКЛАВА!!

Сообщение gjghjc » 11.12.2007 (Вт) 17:45

kibernetics
А вот тебе вопрос.... если время перевалит за полночь.. оно же будет меньше чем 20:00.... Но смена то будет ВТОРАЯ!! :)
Утро добрым не бывает!

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Сообщение kibernetics » 11.12.2007 (Вт) 18:17

gjghjc
ты не понял, как оно перевалит? это же поле "время".
я просто вставил Time как пример

gjghjc
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 659
Зарегистрирован: 13.10.2002 (Вс) 8:28
Откуда: БАЛАКЛАВА!!

Сообщение gjghjc » 11.12.2007 (Вт) 18:37

kibernetics
А так что ко второй смене относится как масса замеренная 11/12/0007 в 20:05 так и 12/12/2007 в 01:05.... Но ведь по твоему коду '01:05' меньше чем '20:05' и следовательно твой код отнесет этот замер к первой смене. Т.е. нужно учитывать не только время но и дату.
Утро добрым не бывает!

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Сообщение kibernetics » 12.12.2007 (Ср) 9:58

gjghjc
так, не придирайся к словам. я же написал: "примерно"
это значит примерно по аналогии.
можно условить так:
Код: Выделить всё
IIF(Время Between #08:00# AND #20:00#,"1 Смена", "2 Смена")

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 12.12.2007 (Ср) 10:28

Пробую так:

sSQL = "SELECT " & TableName & ".DATE_B, Sum(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " , IIf (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " GROUP BY " & TableName & ".DATE_B"


AdodcCalc.RecordSource = sSQL
AdodcCalc.Refresh

Получаю ошибку "Попытка выполнить запрос, который не включает выражение IIF (Time...bla bla как часть статистической функции или группы.

Где нужно подкрутить?

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Сообщение kibernetics » 12.12.2007 (Ср) 10:38

Al Prad
а зачем ты делаешь группировку?
удали последнюю строчку из запроса

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 12.12.2007 (Ср) 10:41

gjghjc писал(а):Ну я бы например ввел еще одно поле куда бы вставлял номер смены
1 или 2
Потом
Код: Выделить всё
SELECT Sum(table1.Massa) AS [Sum-Massa], table1.Date_, table1.Smena
FROM table1
GROUP BY table1.Date_, table1.Smena;


Если нельзя ввести еще одно поле со сменой тогда так

Код: Выделить всё
SELECT Sum(table1.Massa) AS [Sum-Massa], table1.Date_
FROM table1
GROUP BY table1.Date_, ( (time_ BETWEEN #08:00:00# AND #19:59:00#) AND  (time_ BETWEEN #20:00:00# AND #07:59:00#));


Вот глянь вложение версия Access - XP.


Номер смены ввести в исходную таблицу нельзя - она формируется весами (сторонняя компания)

а по второму варианту может получиться так, что одна из смен не работала, получим одну сумму за эту дату, но без информации, какая именно смена отвешивала...

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 12.12.2007 (Ср) 10:52

kibernetics писал(а):Al Prad
а зачем ты делаешь группировку?
удали последнюю строчку из запроса


убрал.

sSQL = "SELECT " & TableName & ".DATE_B, Sum(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName

Получаю "Попытка выполнить запрос, который не включает выражение 'DATE_B' как часть статистической функции или группы."


Ладно. Убираю дату (хотя мне дата вообще-то нужна :)

sSQL = "SELECT Sum(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName

И опять получается Попытка выполнить запрос, который не включает выражение IIF (Time...bla bla как часть статистической функции или группы.

Наверное, я не прав, но такое ощущение, что IIF не может работать внутри SQL-запроса...
Последний раз редактировалось Al Prad 12.12.2007 (Ср) 10:55, всего редактировалось 1 раз.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 12.12.2007 (Ср) 10:54

Суммирование тоже убери.
Lasciate ogni speranza, voi ch'entrate.

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 12.12.2007 (Ср) 11:08

alibek писал(а):Суммирование тоже убери.


Сначала принял это за шутку, но попробовал.

sSQL = "SELECT " & TableName & ".DATE_B," & TableName & ".MASS_Z"
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName

Вывод: IIF работает. Но мне нужна сумма по сменам.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 12.12.2007 (Ср) 11:16

Тогда сделай иначе.
Суммирование это агрегатная функция, ее использование налагает определенные требования к запросу.
Используй вложенный запрос. Либо сумму сделай последним полем, а в группировку включи первые два поля.
Lasciate ogni speranza, voi ch'entrate.

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 12.12.2007 (Ср) 15:27

Так.
Сначала подзапрос.

sSQL = " SELECT * "
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " order by DATE_B, TIME_B"

AdodcCalc.RecordSource = sSQL
AdodcCalc.Refresh

Получаем исходную таблицу плюс столбец SMENA с расставленными сменами 1 или 2 соответственно. Теперь пытаюсь включить этот подзапрос в основной запрос:

sSQL = "SELECT DATE_B, Sum(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " , SMENA "
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " WHERE EXISTS "

'подзапрос
sSQL = sSQL & " (SELECT * "
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " ORDER BY DATE_B, TIME_B)"

sSQL = sSQL & " GROUP BY DATE_B"

получаю "драйвер ODBC dBASE слишком мало параметров. Требуется 1."

если убрать строку
sSQL = sSQL & " , SMENA "
получаю просто сумму по датам (без смены), как если бы было просто
sSQL = "SELECT " & TableName & ".DATE_B, Sum(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " GROUP BY " & TableName & ".DATE_B"

gjghjc
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 659
Зарегистрирован: 13.10.2002 (Вс) 8:28
Откуда: БАЛАКЛАВА!!

Сообщение gjghjc » 12.12.2007 (Ср) 16:59

А кто мешает сделать первый запрос на создание таблицы, а потом уже из нее дергать данные в твою основную базу? Т.е. провести всю операцию не одним запросом а двумя если с подзапросом такие грабли лезут ??
Утро добрым не бывает!

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 13.12.2007 (Чт) 9:46

Делаю в аксессе 2 запроса.
Первый

SELECT IIf(TIME_B>=8 And TIME_B<20,1,2) AS SMENA, *
FROM CBYNKER
ORDER BY DATE_B, TIME_B;

добавляет столбец со сменой.

Второй запрос
SELECT [Первый Запрос].DATE_B, [Первый Запрос].SMENA, Sum([Первый Запрос].MASS_Z) AS [Sum-MASS_Z]
FROM [Первый Запрос]
GROUP BY [Первый Запрос].DATE_B, [Первый Запрос].SMENA;

В итоге получаю то, что и хотел.

Теперь переходим в VB.
Первый запрос
sSQL = " SELECT * "
sSQL = sSQL & " , IIF (TIME_B >= 8 And TIME_B < 20, 1, 2) AS SMENA "
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " ORDER BY DATE_B, TIME_B"

AdodcCalc.RecordSource = sSQL
AdodcCalc.Refresh


А вот со вторым запросом мне непонятно, что я должен подставить вместо первый запрос. Пытаюсь подставить вместо ПервыйЗапрос AdodcCalc.RecordSource :

sSQL = "SELECT AdodcCalc.RecordSet.DATE_B, AdodcCalc.RecordSet.SMENA, Sum(AdodcCalc.RecordSet.MASS_Z) AS [Sum-MASS_Z]"
sSQL = sSQL & " From AdodcCalc.RecordSet"
sSQL = sSQL & " GROUP BY AdodcCalc.RecordSet.DATE_B, AdodcCalc.RecordSet.SMENA"

Adodc1.RecordSource = sSQL
Adodc1.Refresh

Получаю "Объект AdodcCalc.Recordset не найден ядром базы данных MS JET. Проверьте существование объекта и правильность пути"

Видимо, я что-то не то подстваляю вместо ПервогоЗапроса. А что надо?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 13.12.2007 (Чт) 9:57

Откуда твоей базе данных знать о твоем объекте AdodcCalc?
Создай в базе сохраненный запрос и используй имя этого сохраненного запроса.
Lasciate ogni speranza, voi ch'entrate.

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 13.12.2007 (Чт) 13:54

alibek писал(а):Откуда твоей базе данных знать о твоем объекте AdodcCalc?
Создай в базе сохраненный запрос и используй имя этого сохраненного запроса.


Не получается создать запрос в моей базе, т.к. в ней нет информации о полях внешнего dbf-файла... И о его имени и пути тоже.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 13.12.2007 (Чт) 14:08

Ты можешь подключить эти DBF-файлы как связанные поля.
В крайнем случае используй вложенный запрос, что-то типа:

select *
from table1
join (select * from ...) as table2 on ...

Только у Access ограниченная поддержка вложенных запросов, может он не сумеет такой запрос обработать.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 13.12.2007 (Чт) 14:11

Попробуй такое:
Код: Выделить всё
SELECT DATE_B, IIf(TIME_B>=8 And TIME_B<20,1,2), SUM(MASS_Z)
FROM CBYNKER
GROUP BY DATE_B, IIf(TIME_B>=8 And TIME_B<20,1,2)
Lasciate ogni speranza, voi ch'entrate.

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 13.12.2007 (Чт) 15:07

alibek писал(а):Попробуй такое:
Код: Выделить всё
SELECT DATE_B, IIf(TIME_B>=8 And TIME_B<20,1,2), SUM(MASS_Z)
FROM CBYNKER
GROUP BY DATE_B, IIf(TIME_B>=8 And TIME_B<20,1,2)


YES!
Заработало!

Да, SQL - это вам не в баню сходить.

Всем спасибо за оказанную помощь, а особенно alibek за окончательный рабочий вариант и kibernetics за Iif.

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Сообщение kibernetics » 13.12.2007 (Чт) 17:39

alibek
оригинально придумал :D
молоток

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 25.01.2008 (Пт) 17:06

Добрый день!

Извините за возвращение к старой теме.

Обнаружилась досадная неточность при определении второй смены. Например, имеются записи за 25 и 26 числа месяца. Первая смена работает 25-го с 8.00 до 19.59 часов. А вот вторая смена работает с 20.00 до 23.59 25-го числа плюс с 0.00 до 7.59 26-го числа. Затем 26-го работает 1-я смена до 19.59 и далее вторая смена с 20.00 до 23.59 и т.д. Так вот, при таком запросе у меня суммируется например, по 26 числу для второй смены записи, с 20.00 до 00.00 + с 00.00 до 8.00.
Но записи с 0.00 до 8.00 относятся ко второй смене _предыдущего_ дня, а не текущего! Т.е. записи второй смены раскиданы по двум датам подряд, но сумма их должна относится к первой дате.
На словах тяжело объяснить, добавлю рисунок в приложении, где показано как неправильно происходит суммирование и как оно должно происходить.

Всвязи с этим пробовал изменить запрос так:

sSQL = ""
sSQL = sSQL & "SELECT IIf(TIME_B>=0 AND TIME_B<8,DATE_B - 1,DATE_B ) as DateRecalc, "
sSQL = sSQL & " IIf(TIME_B>=8 AND TIME_B<20,1,2) as SMENA, SUM(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " GROUP BY DateRecalc, IIf(TIME_B>=8 AND TIME_B<20,1,2)"

т.е. пытаюсь ввести новый столбец, который будет равен дате DATE_B, если время не с 0 до 8 или на день меньше (DATE_B-1) в противном случае.
Конечно, что-то неправильно , т.к. получаю сообщение You tried to execute querry that doesn't include the specified instruction 'IIf(TIME_B>=0 AND TIME_B<8,DATE_B - 1,DATE_B )' as part of an aggregate function. Т.е. "вы пытаетесь выполнить запрос, который не включает инструкцию IIF... как часть агрегатной функции.

Как мне подправить запрос для получения верного результата?
Спасибо.
Вложения
Smeni.xls
(18 Кб) Скачиваний: 80

Al Prad
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 16.08.2007 (Чт) 12:46
Откуда: Одесса

Сообщение Al Prad » 25.01.2008 (Пт) 19:43

Подправил по аналогии с предыдущим решением :oops: :

sSQL = ""
sSQL = sSQL & "SELECT IIf(TIME_B>=0 AND TIME_B<8,DATE_B - 1,DATE_B ) as DateRecalc, "
sSQL = sSQL & " IIf(TIME_B>=8 AND TIME_B<20,1,2) as SMENA, SUM(MASS_Z) AS [Sum_MASS_Z]"
sSQL = sSQL & " FROM " & TableName
sSQL = sSQL & " GROUP BY IIf(TIME_B>=0 AND TIME_B<8,DATE_B - 1,DATE_B ), IIf(TIME_B>=8 AND TIME_B<20,1,2)"
sSQL = sSQL & " ORDER BY IIf(TIME_B>=0 AND TIME_B<8,DATE_B - 1,DATE_B ) DESC, IIf(TIME_B>=8 AND TIME_B<20,1,2) DESC"

Вроде работает, придется проверить путем ручного пересчитывания :shock:


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: The trick и гости: 8

    TopList