Профессия — 1С

Рукопашный бой Карташ

Категории

Минимальное значение нескольких полей

рубрики: SQL | Дата: 30 Июль, 2016

Рассмотрим следующую ситуацию. Допустим у нас есть таблица с несколькими однотипными полями.
И нам надо для каждой записи этой таблицы получить минимальное или максимальное значение из
этих нескольких полей.




Ну и чтобы было веселее добавим условие, что пустые значения надо отбрасывать.
Для примера возьмем таблицу с 4-я полями. В первом поле будет уникальный
идентификатор какого-нибудь документа, а в трех других даты:

Docs DateBeg DateEnd DateChange
Doc_1 2016-02-29 00:00:00 2018-03-01 00:00:00 2017-05-15 00:00:00
Doc_2 2017-11-21 00:00:00 2016-06-18 00:00:00 1753-01-01 00:00:00

Для начала создадим нашу тестовую таблицу:


/*Создаем тестовую таблицу*/
Create Table #DocDate (Docs VarChar(10), DateBeg DateTime, DateEnd DateTime, DateChange DateTime)

Insert #DocDate
Select
    'Doc_1'	AS Docs,
    '20160229'	AS DateBeg,
    '20180301'	AS DateEnd,
    '20170515'	AS DateChange

Union All

Select
    'Doc_2'	AS Docs,
    '20171121'	AS DateBeg,
    '20160618'	AS DateEnd,
    '17530101'	AS DateChange

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

А теперь подумаем как лучше реализовать поставленную задачу.
Первое, что приходит на ум – это использовать конструкцию CASE.
Но даже просто для 3-х полей получается достаточно большой и запутанный кусок кода.
А если еще учесть, что надо исключить пустые значения, то и вовсе беда.




Поэтому для поля где нужна минимальная дата создадим вложенный запрос с использованием
агрегатной функции MIN(). В итоге получаем вот такой достаточно простой код:


/*Создаем тестовую таблицу*/
Create Table #DocDate (Docs VarChar(10), DateBeg DateTime, DateEnd DateTime, DateChange DateTime)

Insert #DocDate
Select
    'Doc_1'		AS Docs,
    '20160229'	AS DateBeg,
    '20180301'	AS DateEnd,
    '20170515'	AS DateChange

Union All

Select
    'Doc_2'		AS Docs,
    '20171121'	AS DateBeg,
    '20160618'	AS DateEnd,
    '17530101'	AS DateChange

/*Выборка из тестовой таблицы*/
Select
    DocDate.*,
    (
    Select 
        MIN(Dates)
    From
        (Select DateBeg AS Dates Where DateBeg <> '17530101'

        Union All

        Select DateEnd Where DateEnd <> '17530101'

        Union All

        Select DateChange Where DateChange <> '17530101') DMin
    ) AS DateMin

From #DocDate AS DocDate

Drop Table #DocDate

Выполняем код и получаем вот такой результат:

Docs DateBeg DateEnd DateChange DateMin
Doc_1 2016-02-29 00:00:00 2018-03-01 00:00:00 2017-05-15 00:00:00 2016-02-29 00:00:00
Doc_2 2017-11-21 00:00:00 2016-06-18 00:00:00 1753-01-01 00:00:00 2016-06-18 00:00:00

Понятно, что использовать это можно не только для полей с датами, но и для других типов тоже.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

   

2018г. Профессия — 1С. Обмен опытом по программированию в 1С