Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » SQL запрос

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

Открыть новую тему     Написать ответ в эту тему

DenSyo

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
NeoAnomaly
следующая конструкция должна бы вам подойти, но присоединюсь к вопросу выше...

Код:
SELECT [t1].* FROM mytab [t1]  
INNER JOIN ( SELECT MAX([id]) AS [max_id], [ParentId], [Level] FROM mytab GROUP BY [ParentId], [Level] ) [t2] ON [t2].[max_id]=[t1].[id]


Всего записей: 218 | Зарегистр. 19-01-2008 | Отправлено: 07:39 13-12-2018 | Исправлено: DenSyo, 07:49 13-12-2018
NeoAnomaly

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
YuriyRR, здесь уровень - это просто значение из предметной области - уровень в корпоративной иерархии.
 
Пока гуглил наткнулся на точно такую же структуру данных. В БД ФИАС данные организованы похожим образом, поэтому можно задачу переписать с использованием хорошо известной нам всем предметной области:
 

Код:
 
Id     ParentId           Level        Field  
----------------------------------------------  
1        null             Область      Амурская  
2        1                Район        Архаринский  
3        1                Район        Белогорский  
4        1                Район        Зейский  
5        2                Город        Белогорск  
6        2                Город        Благовещенск  
7        3                Город        Свободный
8        7                Улица        Ленина
9        6                Улица        Ленина
 

 
И вот нужна мне именно улица Ленина, но только в Городе Благовещенск из Района Белогорский. И в результате запроса я должен собрать весь путь, т.е. Амурская -> Белогорский -> Благовещенск -> Ленина:
 

Код:
 
Id     ParentId           Level        Field  
----------------------------------------------  
1        null             Область      Амурская  
3        1                Район        Белогорский  
6        2                Город        Благовещенск  
9        6                Улица        Ленина
 

 
Т.е. в процессе поиска улицы на уровнях Район и Город я должен проверить, что значение [Field] равно Белогорский и Благовещенск соответственно.
 
DenSyo, скорее из-за неправильной постановки задачи, немного не то получается.

Всего записей: 418 | Зарегистр. 23-03-2010 | Отправлено: 08:45 13-12-2018
DenSyo

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
т.е. Амурская -> Белогорский -> Благовещенск -> Ленина

может все же Амурская - Архаринский - Благовещенск - Ленина ?  
либо Амурская - Белогорский - Свободный - Ленина...
 
вложенность селектов в конструкции надо сделать по максимальному числу наследования в таблице, либо с запасом

Код:
SELECT [tt].*, IIF([tt].[ParentId] IS NOT NULL, ( SELECT [t1].[Field]
  +IIF([t1].[ParentId] IS NOT NULL, ' - '+( SELECT [t2].[Field]  
  +IIF([t2].[ParentId] IS NOT NULL, ' - '+( SELECT [t3].[Field]  
  +IIF([t3].[ParentId] IS NOT NULL, ' - '+( SELECT [t4].[Field]  
  +IIF([t4].[ParentId] IS NOT NULL, ' - '+( SELECT [t5].[Field]  
  FROM heap.dbo.tree [t5] WHERE [t5].[Id]=[t4].[ParentId] ), '')  
  FROM heap.dbo.tree [t4] WHERE [t4].[Id]=[t3].[ParentId] ), '')  
  FROM heap.dbo.tree [t3] WHERE [t3].[Id]=[t2].[ParentId] ), '')  
  FROM heap.dbo.tree [t2] WHERE [t2].[Id]=[t1].[ParentId] ), '')  
  FROM heap.dbo.tree [t1] WHERE [t1].[Id]=[tt].[ParentId] ), NULL) AS [FieldsParents]  
FROM heap.dbo.tree [tt]  

Всего записей: 218 | Зарегистр. 19-01-2008 | Отправлено: 10:00 13-12-2018 | Исправлено: DenSyo, 11:07 13-12-2018
NeoAnomaly

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
может все же Амурская - Архаринский - Благовещенск - Ленина ?  

DenSyo, да, вы правы. За запрос спасибо, буду разбираться.

Всего записей: 418 | Зарегистр. 23-03-2010 | Отправлено: 11:38 13-12-2018
DenSyo

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
NeoAnomaly
конструкция с джойнами позволит без потери производительности собрать несколько полей из предков

Код:
SELECT [tt].*, IIF([t1].[Id] IS NULL, NULL, [t1].[Field]+' '+[t1].[Level]  
    +IIF([t2].[Id] IS NULL, '', ' - '+[t2].[Field]+' '+[t2].[Level]  
    +IIF([t3].[Id] IS NULL, '', ' - '+[t3].[Field]+' '+[t3].[Level]  
    +IIF([t4].[Id] IS NULL, '', ' - '+[t4].[Field]+' '+[t4].[Level]  
    +IIF([t5].[Id] IS NULL, '', ' - '+[t5].[Field]+' '+[t5].[Level]
  ))))) AS [FParents],  
  IIF([t1].[Id] IS NULL, NULL, CAST([t1].[Id] AS VARCHAR)  
    +IIF([t2].[Id] IS NULL, '', ';'+CAST([t2].[Id] AS VARCHAR)  
    +IIF([t3].[Id] IS NULL, '', ';'+CAST([t3].[Id] AS VARCHAR)  
    +IIF([t4].[Id] IS NULL, '', ';'+CAST([t4].[Id] AS VARCHAR)  
    +IIF([t5].[Id] IS NULL, '', ';'+CAST([t5].[Id] AS VARCHAR)
  ))))) AS [IdsParents],  
  IIF([t1].[Id] IS NULL, 0, 1  
    +IIF([t2].[Id] IS NULL, 0, 1  
    +IIF([t3].[Id] IS NULL, 0, 1  
    +IIF([t4].[Id] IS NULL, 0, 1  
    +IIF([t5].[Id] IS NULL, 0, 1
  ))))) AS [CountParents]  
FROM heap.dbo.tree [tt]  
LEFT MERGE JOIN heap.dbo.tree [t1] ON [tt].[ParentId] IS NOT NULL AND [t1].[Id]=[tt].[ParentId]  
LEFT MERGE JOIN heap.dbo.tree [t2] ON [t1].[ParentId] IS NOT NULL AND [t2].[Id]=[t1].[ParentId]  
LEFT MERGE JOIN heap.dbo.tree [t3] ON [t2].[ParentId] IS NOT NULL AND [t3].[Id]=[t2].[ParentId]  
LEFT MERGE JOIN heap.dbo.tree [t4] ON [t3].[ParentId] IS NOT NULL AND [t4].[Id]=[t3].[ParentId]  
LEFT MERGE JOIN heap.dbo.tree [t5] ON [t4].[ParentId] IS NOT NULL AND [t5].[Id]=[t4].[ParentId]  

Всего записей: 218 | Зарегистр. 19-01-2008 | Отправлено: 05:11 14-12-2018 | Исправлено: DenSyo, 06:09 14-12-2018
VasiliySuhomlin



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Пожалуйста, помогите чайнику составить запрос! Задача - остатки на складе. Например: есть две таблицы:
t1 : суммарное новое поступление со средней стоимостью за месяц
ID(char(3)), Month(int), Q-ty(decimal), Cost(money)
-------------^------------^---------------^--------------
001               0                50                   400
001               1                100                 777
001               2                150                 1111
001               3                200                 1666
где Month=0 - сальдо на начало
 
t2 : суммарный выход
ID(char(3)), Month(int), Q-ty(decimal), Cost(money)
-------------^------------^---------------^--------------
001               1                120  
001               2                140
001               3                220
 
Нужно заполнять поле Cost в таблице t2. Спасибо.

Всего записей: 36 | Зарегистр. 03-12-2004 | Отправлено: 14:20 10-04-2019
vikkiv



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
VasiliySuhomlin
на основании первой таблицы вычисляешь стоимость единицы продукции (например ... [cost]/[q-ty] as unit_cost ...)
потом этот результат outer join-ишь со второй (по полям [id],[month]) и умножаешь на количество в конечной таблице
по факту получается:
---------------
select t2.[id],t2.[month],t2.[q-ty]*t1.[cost]/t1.[q-ty] as cost
from t2 left join t1 on t1.[id]=t2.[id] and t1.[month]=t2.[month]
---------------
по необходимости можно ещё проверки разные добавить (напр на null или ноль), конвертации в нужный тип данных, логику всякую напр. что делать если поступлений небыло (т.е. в t1 нет данных для данной комбинации композитного ключа), группировки/агрегации если строки не уникальны и т.д. и т.п.

Всего записей: 747 | Зарегистр. 10-11-2005 | Отправлено: 17:24 10-04-2019
VasiliySuhomlin



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vikkiv
Спасибо за оперативное реагирование. Да, пример самый беспроблемный - все поля заполнены.
Я опишу алгоритм вычисления:
 
t2:  
ID(char(3)), Month(int), Q-ty(decimal), Cost(money)  
-------------^------------^---------------^--------------  
001               1              120       t2.Cost[1]= t2.Q-ty[1]'*(t1.Cost[0]+t1.Cost[1])/(t1.Q-ty[0]+t1.Q-ty[1]);
001               2              140       t2.Cost[2]= t2.Q-ty[2]'*(t2.Cost[1]+t1.Cost[2])/(t2.Q-ty[1]+t1.Q-ty[2]);
001               3              220       t2.Cost[3]= t2.Q-ty[3]'*(t2.Cost[2]+t1.Cost[3])/(t2.Q-ty[2]+t1.Q-ty[3]);
 
т.е. последующее значение  поля t2.Cost зависит от предыдущей. Выход найден сохранением промежуточных данных во временную таблицу. Битую неделю потратил чтобы, найти красивый код запроса. Да и незнание матчасти терзает. Может кто проходил одним select-ом?

Всего записей: 36 | Зарегистр. 03-12-2004 | Отправлено: 20:37 10-04-2019
vikkiv



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
VasiliySuhomlin
это всё пока вангование над хрустальным шаром, хотя некоторый прогресс
уже хотя-бы в том что вдруг выявляется нужная формула вычислений, для
прояснения ситуации неплохо-бы знать версию/редакцию базы данных чтобы
приводить пример / путь решения на нужном диалекте (т.к. функции обращения
к предыдыщей строке в разных системах отличаются, кроме того наверняка ещё
и год кроме месяца есть), ну и в конце концов твоя временная таблица ведь тоже
не сама нарисовалась и заполнилась, так что давай логику или код как это сделал.

Всего записей: 747 | Зарегистр. 10-11-2005 | Отправлено: 21:04 10-04-2019
VasiliySuhomlin



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vikkiv
Пардон! База на MS SqlServer 2012. Данные с 2013 года. Чтобы долгую резину не тянуть, выборкой отбираю во временную таблицу данные нужного склада и года. Некоторыми манипуляциями получаю (опять таки во временную таблицу) вышеуказанные t1 и t2.  
Цель: Получить средневзвешанную себестоимость материалов на складе (да простите за термины моего главбуха) за отчетный период.
Формула: (Ст-ть на начало + Ст-ть за период) / (К-во на начало + К-во за период)
Чтобы не стояли над душою, пришлось соорудить времянку: Чтобы получить отчет за март процедура выполняет отчет за январь - сохраняет во вр.табл1, за февраль - вр.табл2 (что будет следующие месяцы!). Код процедуры получился длинный, не знаю куда выложить.  
Решение проблемы лежит в заполнении полей Cost в таблице t2. И еще: назначение этой таблицы лучше перевести в учет остатков материала на начало отчетного периода.

Всего записей: 36 | Зарегистр. 03-12-2004 | Отправлено: 07:33 11-04-2019 | Исправлено: VasiliySuhomlin, 09:51 11-04-2019
Steepe_Hare



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Господа, помогите составить SQL-запрос, пожалуйста.
Нужно отсортировать таблицу по полю, которого нет.
 
Есть такая таблица:
1. Команда
2. Кол-во побед
3. Кол-во ничьих
4. Кол-во поражений
 
и нужно их расположить по количеству игр (победы +ничьи + поражения)
 
Заранее благодарен

Всего записей: 1162 | Зарегистр. 27-10-2001 | Отправлено: 04:32 26-04-2019 | Исправлено: Steepe_Hare, 04:32 26-04-2019
exteris

Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Код:
select команда, победы+ничьи+поражения as игры
from таблица
order by игры  

Всего записей: 382 | Зарегистр. 14-04-2003 | Отправлено: 07:16 26-04-2019
Steepe_Hare



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
exteris
 
спасибо!

Всего записей: 1162 | Зарегистр. 27-10-2001 | Отправлено: 04:44 27-04-2019
Steepe_Hare



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ребята, помогите написать правильный запрос.
 
Есть таблица из трех полей:
Name, Quantity, Income
 
Пример таблицы:
Иванов, 15, 100
Петров, 15, 89
Сидоров, 15, 92
Иванов, 15, 100
Иванов, 15, 105
Иванов, 17, 115
 
Пользователь задает поля для Name  и Quantity и нужно посчитать, сколько раз в таких записях встречаются разнообразные варианты Income (для Иванова и 15: 100 встречается 2 раза, а 105 - 1 раз)
 
 
Пока я просто делаю селект по двум полям, а потом прохожусь по получившейся выборке от первой до последней записи и обрабатываю третье поле Income, но чувствую, что это неэффективно

Всего записей: 1162 | Зарегистр. 27-10-2001 | Отправлено: 19:38 25-11-2019
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Steepe_Hare
SELECT Income, COUNT(*) FROM TABLE WHERE Name = '...' AND Quantity = ... GROUP BY Income

Всего записей: 15100 | Зарегистр. 20-09-2014 | Отправлено: 19:56 25-11-2019 | Исправлено: Mavrikii, 19:57 25-11-2019
Steepe_Hare



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mavrikii
 
Спасибо за ответ, но так даже медленнее заработало((

Всего записей: 1162 | Зарегистр. 27-10-2001 | Отправлено: 19:15 01-12-2019
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Steepe_Hare

Цитата:
Спасибо за ответ, но так даже медленнее заработало((

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

Всего записей: 15100 | Зарегистр. 20-09-2014 | Отправлено: 23:18 01-12-2019 | Исправлено: Mavrikii, 23:19 01-12-2019
Steepe_Hare



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mavrikii
 
индексов нет, а как лучше их построить?

Всего записей: 1162 | Зарегистр. 27-10-2001 | Отправлено: 15:12 03-12-2019
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Steepe_Hare

Цитата:
а как лучше их построить?

что то типа
Цитата:
CREATE INDEX my_index ON tablename (Name, Quantity, Income);

возможно Income не нужно, не помню используется ли он при группировке.

Всего записей: 15100 | Зарегистр. 20-09-2014 | Отправлено: 22:09 03-12-2019
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Здрасти здешние жители.
Это не критично, но решил полюбопытствовать... Нужен всего лишь один простой запрос в формате SQL'92 в более приличном виде чем придумал.

Код:
 
      Drop Table Таблица;
      Create Table Таблица (ID AutoInc);
      Insert Into Таблица (ID) Values (''), (''), (''), (''), (''), (''), (''), (''), (''), ('');
      Select * From Таблица
 

Тоесть добавляется 10 пустых записей. Можно как-то более культурно это сделать? Просто мне нужно 100 пустых строк, а так писать не очень красиво.
P.S. Запрос для одного Delphi компонента, который яко-бы поддерживает SQL'92, но не факт...

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 13:49 18-03-2020
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » SQL запрос


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru