Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> Как организовать "срез последних/последних"?          
Vofka Подменю пользователя
сообщение 11.10.10, 8:25
Сообщение #1

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13948
Из: Киев
Спасибо сказали: 4514 раз
Рейтинг: 3635.6

Привет!

Интересует вопрос, как организовать срез последних?

Т.е. есть таблица: id | id_chel (ид человека) | mesto_raboty (место работы) | data (дата). В таблице хранятся люди, место работы и дата. Меняя место работы - мы просто добавляем новую запись, например

1 | Петров | ЧП "У Васи" | 1.10.2010
2 | Иванов | ЧП "У Пети" | 1.10.2010
3 | Петров | ЧП "У Коли" | 5.10.2010
...

Это не связано с 1С. Это просто таблица в какой-нибудь СУБД (MSSQL, MySQL...). Интересует как из такой таблицы получить то, что в 1С называется срезом первых/последних. Интересна сама логика, т.е. указать какое-то условие в запросе или использовать какую-то специальную функцию.

Log1c Подменю пользователя
сообщение 25.01.11, 15:50
Сообщение #2

Завсегдатай
Иконка группы
Группа: Местный
Сообщений: 178
Из: Харьков
Спасибо сказали: 27 раз
Рейтинг: 0

Цитата(Vofka @ 11.10.10, 9:25) *
Привет!

Интересует вопрос, как организовать срез последних?

Т.е. есть таблица: id | id_chel (ид человека) | mesto_raboty (место работы) | data (дата). В таблице хранятся люди, место работы и дата. Меняя место работы - мы просто добавляем новую запись, например

1 | Петров | ЧП "У Васи" | 1.10.2010
2 | Иванов | ЧП "У Пети" | 1.10.2010
3 | Петров | ЧП "У Коли" | 5.10.2010
...

Это не связано с 1С. Это просто таблица в какой-нибудь СУБД (MSSQL, MySQL...). Интересует как из такой таблицы получить то, что в 1С называется срезом первых/последних. Интересна сама логика, т.е. указать какое-то условие в запросе или использовать какую-то специальную функцию.


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


Signature
1С:Предприятие 7.7 БУ + ТиС + ЗП и кадры 7.70.031 для Украины
1С:Предприятие 8.3 УТП для Украины 1.2.28.1 (обычные формы)

Flexy Подменю пользователя
сообщение 25.01.11, 16:12
Сообщение #3

Танцор с Бубном
Иконка группы
Группа: Местный
Сообщений: 1121
Из: Днепра
Спасибо сказали: 230 раз
Рейтинг: 0

SELECT Max(data), id, id_chel, mesto_raboty
from Ваша База
WHERE id='код'
group by id()

Спасибо сказали: Vofka,

Vofka Подменю пользователя
сообщение 26.01.11, 9:20
Сообщение #4

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13948
Из: Киев
Спасибо сказали: 4514 раз
Рейтинг: 3635.6

Цитата
С понятием среза данных не знаком. Сформулируйте пожалуйста что нужно получить в результирующей выборке?

Нужно получить последние (по дате добавления) записи.

Цитата
SELECT Max(data), id, id_chel, mesto_raboty
from Ваша База
WHERE id='код'
group by id()

Допустим можно smile.gif . Ещё варианты есть? smile.gif

World1С Подменю пользователя
сообщение 26.01.11, 9:36
Сообщение #5

Оратор
Иконка группы
Квалифицированному 1С программисту
Группа: Местный
Сообщений: 358
Из: г.Луганск, обл.Луганская
Спасибо сказали: 110 раз
Рейтинг: 0

Select * 
from base as b1
where Date in (Select MAX(Date) from base as b2 where b1.id=b2.id)


Ну вот как то так можно попробовать... Но текст не претендует на звание лучшего.

Select Max(Date), id 
from base
group by id (ну и все остальные поля которые будут в селекте после id)


Signature
В наше время люди всему знают цену, но понятия не имеют о подлинной ценности.
Оскар Уайлд

Спасибо сказали: Vofka,

РомаZ Подменю пользователя
сообщение 09.06.11, 13:35
Сообщение #6

Молчаливый
*
Группа: Пользователи
Сообщений: 1
Спасибо сказали: 0 раз
Рейтинг: 0

Примерно так:

// Входные параметры: 
//           @someDate: DATETIME

SELECT
    srcTable.id
    ,srcTable.Name
    ,srcTable.someOtherProperty
    ,srcTable.Date AS [Дата последнего изменения]
    ,@someDate AS [Дата среза]
    
FROM
    dbTable AS srcTable    // отсюда получаем информацию по id-ам из constraintaTable
    
    INNER JOIN
    (    // Получение последних идентификаторов на дату с дополнительными условиями
        SELECT
            dbTable.id,
            max(dbTable.data)
        FROM dbTable
        WHERE dbTable.data < @someDate
            AND дополнительные условия на отбор по данным таблицы
    ) AS constraintTable
    
    ON srcTable.id = constraintTable.id
    AND srcTable.data = constraintTable.data


Цитата(РомаZ @ 09.06.11, 13:24) *


забыл "Group By".

Вот код с исправлением:

// Входные параметры: 
//           @someDate: DATETIME

SELECT
    srcTable.id
    ,srcTable.Name
    ,srcTable.someOtherProperty
    ,srcTable.Date AS [Дата последнего изменения]
    ,@someDate AS [Дата среза]
    
FROM
    dbTable AS srcTable    // отсюда получаем информацию по id-ам из constraintaTable
    
    INNER JOIN
    (    // Получение последних идентификаторов на дату с дополнительными условиями
        SELECT
            dbTable.id,
            max(dbTable.data)
        FROM dbTable
        WHERE dbTable.data < @someDate
        //    AND дополнительные условия на отбор по данным таблицы
        
        [b]GROUP BY dbTable.id[/b]
        
    ) AS constraintTable
    
    ON srcTable.id = constraintTable.id
    AND srcTable.data = constraintTable.data

Pepe Подменю пользователя
сообщение 09.06.11, 14:55
Сообщение #7

Почти крутой
Иконка группы
Группа: Местный
Сообщений: 1434
Из: Ужгород
Спасибо сказали: 761 раз
Рейтинг: 230

Можно построить индекс и отбор по полю дата, можно без индекса найти последнюю запись и идти назад по условию. При работе с ДБФ легко в Visual Foxpro, да и в 1С реализуется, если я правильно понял задание.

szhukov Подменю пользователя
сообщение 07.09.11, 14:27
Сообщение #8

Молчаливый
*
Группа: Пользователи
Сообщений: 1
Спасибо сказали: 0 раз
Рейтинг: 0

Цитата(РомаZ @ 09.06.11, 14:35) *
Примерно так:

// Входные параметры: 
//           @someDate: DATETIME

SELECT
    srcTable.id
    ,srcTable.Name
    ,srcTable.someOtherProperty
    ,srcTable.Date AS [Дата последнего изменения]
    ,@someDate AS [Дата среза]
    
FROM
    dbTable AS srcTable    // отсюда получаем информацию по id-ам из constraintaTable
    
    INNER JOIN
    (    // Получение последних идентификаторов на дату с дополнительными условиями
        SELECT
            dbTable.id,
            max(dbTable.data)
        FROM dbTable
        WHERE dbTable.data < @someDate
            AND дополнительные условия на отбор по данным таблицы
    ) AS constraintTable
    
    ON srcTable.id = constraintTable.id
    AND srcTable.data = constraintTable.data


забыл "Group By".

Вот код с исправлением:

// Входные параметры: 
//           @someDate: DATETIME

SELECT
    srcTable.id
    ,srcTable.Name
    ,srcTable.someOtherProperty
    ,srcTable.Date AS [Дата последнего изменения]
    ,@someDate AS [Дата среза]
    
FROM
    dbTable AS srcTable    // отсюда получаем информацию по id-ам из constraintaTable
    
    INNER JOIN
    (    // Получение последних идентификаторов на дату с дополнительными условиями
        SELECT
            dbTable.id,
            max(dbTable.data)
        FROM dbTable
        WHERE dbTable.data < @someDate
        //    AND дополнительные условия на отбор по данным таблицы
        
        [b]GROUP BY dbTable.id[/b]
        
    ) AS constraintTable
    
    ON srcTable.id = constraintTable.id
    AND srcTable.data = constraintTable.data


Не взлетит, потому что вложенный запрос:
        SELECT
            dbTable.id,
            max(dbTable.data)
        FROM dbTable
        WHERE dbTable.data < @someDate


вернет все записи smile.gif

Это делается не так

Vofka Подменю пользователя
сообщение 31.07.12, 16:33
Сообщение #9

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13948
Из: Киев
Спасибо сказали: 4514 раз
Рейтинг: 3635.6

Апну тему smile.gif

Цитата(Flexy @ 25.01.11, 17:12) *
SELECT Max(data), id, id_chel, mesto_raboty
from Ваша База
WHERE id='код'
group by id()

Так и что это получится? Запрос вообще по ходу не отработает, потому что нет группировок по остальным полям. А если добавить группировки, то по всем полям, то получится на выходе эта же таблица в исходном виде.

Цитата(World1С @ 26.01.11, 10:36) *
Select * from base as b1 where Date in (Select MAX(Date) from base as b2 where b1.id=b2.id)

По-моему так нельзя. Какие связи в условии IN ?

Цитата(World1С @ 26.01.11, 10:36) *
Select Max(Date), id from base group by id (ну и все остальные поля которые будут в селекте после id)

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

Цитата(Pepe @ 09.06.11, 15:55) *
Можно построить индекс и отбор по полю дата, можно без индекса найти последнюю запись и идти назад по условию. При работе с ДБФ легко в Visual Foxpro, да и в 1С реализуется, если я правильно понял задание.

Речь идет про чистый SQL запрос.

Т.е. не один вариант в этой теме, по-моему, не правильный. Предложу свой:

SELECT
    id,
    id_chel,
    mesto_raboty,
    data
FROM
    table AS table
    INNER JOIN
        (
        SELECT
            Max(Data) AS data,
            id_chel
        FROM
            table AS table
        GROUP BY
            id_chel
        ) AS filter
    ON table.id_chel = filter.id_chel
        AND table.data = filter.data

Vola Подменю пользователя
сообщение 19.09.22, 14:59
Сообщение #10

Молчаливый
*
Группа: Пользователи
Сообщений: 1
Спасибо сказали: 0 раз
Рейтинг: 0

Vofka @ 11.10.10, 8:25 * ,

А можно воспользоваться оконной аналитической функцией FIRST_VALUE

--Создание временной таблицы с начальными данными, предварительно проверив временную таблицу на существование
IF OBJECT_ID(N'tempdb..#InitialData', N'U') IS NOT NULL DROP TABLE dbo.#InitialData

   SELECT 1 id, 'Петров' id_chel, 'ЧП "У Васи"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data]
   INTO #InitialData
UNION ALL
   SELECT 2 id, 'Иванов' id_chel, 'ЧП "У Пети"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data]
UNION ALL
   SELECT 3 id, 'Петров' id_chel, 'ЧП "У Коли"' mesto_raboty, CONVERT(date, '2010.10.05', 121) [data]

--дата среза
DECLARE @date date = '2010.10.02'

--Требуемый запрос
SELECT DISTINCT
       t.id_chel
     , FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
     , FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
  FROM dbo.#InitialData AS t
WHERE t.[data] <= @date

--Удаление временной таблицы после использования
IF OBJECT_ID(N'tempdb..#InitialData', N'U') IS NOT NULL DROP TABLE dbo.#InitialData


Результат для даты 2010.10.02:
---------------------------------------------------------
id_chel | last_mesto_raboty | last_data_raboty
---------------------------------------------------------
Иванов | ЧП "У Пети" | 2010-10-01
Петров | ЧП "У Васи" | 2010-10-01



И тоже самое в другой форме:

-- с использованием CTE

--дата среза
DECLARE @date date = '2010.10.05'

;WITH
InitialData AS (
      --таблица с начальными данными
      SELECT 1 id, 'Петров' id_chel, 'ЧП "У Васи"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data] UNION ALL
      SELECT 2 id, 'Иванов' id_chel, 'ЧП "У Пети"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data] UNION ALL
      SELECT 3 id, 'Петров' id_chel, 'ЧП "У Коли"' mesto_raboty, CONVERT(date, '2010.10.05', 121) [data]
)
--Требуемый запрос
SELECT DISTINCT
       t.id_chel
     , FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
     , FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
  FROM dbo.#InitialData AS t
WHERE t.[data] <= @date


Результат для даты 2010.10.05:
---------------------------------------------------------
id_chel | last_mesto_raboty | last_data_raboty
---------------------------------------------------------
Иванов | ЧП "У Пети" | 2010-10-01
Петров | ЧП "У Коли" | 2010-10-05

Если, при данных исходных данных, в обоих вариантах задать дату меньше 2010-10-01, то в результате получим пустой набор данных.

Цитата(Vola @ 19.09.22, 14:50) *
SELECT DISTINCT
       t.id_chel
     , FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
     , FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
  FROM dbo.#InitialData AS t
WHERE t.[data] <= @date



И, конечно, тут опечатка (во втором листинге - с использованием CTE)
вместо
FROM dbo.#InitialData AS t

надо использовать
FROM InitialData AS t

Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 28.03.24, 18:07
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!