powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как решитить такую задачу на SQL?
12 сообщений из 12, страница 1 из 1
Как решитить такую задачу на SQL?
    #32022592
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С помощью такого запроса:

select s.id,
date1 = case h.id when 658 then h.date else null end,
val1 = case h.id when 658 then h.value else null end,
date2 = case h.id when 659 then h.date else null end,
val2 = case h.id when 659 then h.value else null end
from sc656 s left join _1sconst h ON s.id=h.objid and h.id in (658,659)
where h.date <= '20000820'

получаем следующую таблицу:

А 2001-01-01 10 нулл нулл
А 2001-08-10 20 нулл нулл
А нулл нулл 2001-01-01 10
А нулл нулл 2001-08-01 20

Нужно из такой таблицы получить такую:

А 2001-08-10 20 2001-08-01 20

По "человечески" как делать понятно - проходим каждую строку и в каждой колонке ищем значение по максимуму даты и это значение записываем как результат. А как это сделать на SQL? Причем желательно в одном запросе и без временных таблиц.
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022595
©+Vintik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думается мне что нужно выборку надо делать из трёх таблиц
1. Умножить множесва (поличим все возможные пересечения)
2. фильтруем

table1*table2a*table2b -> filter = и получим то что надо


а вот и все готовое
у меня все работало


select a.ID, date1 = b.Date, val1 = b.value, date2 = c.Date, val2 = c.value
from sc656 a
INNER JOIN join _1sconst b ON a.id=b.obj
INNER JOIN join _1sconst c ON a.id=c.obj
where b.id = 658
and c.id = 659
and b.date <= '20000820'
and c.date <= '20000820'

Удачи
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022606
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если твой запрос это конечный вариант, то это не совсем то что нужно. В результате не должно быть повторяющихся строка с ключом a.id, в каждой из колонок (date1,val1) - date1 должна быть максимальной в пределах ключа, а val1 должно быть значением из этой строки (где дата максимальна). Вот так. Какие еще будут идеи?

Ты сам с 1С случайно не работаешь? Если работаешь, то наверно тебе знакома эта задача - выборка у справочника более чем двух периодических реквизитов на определенную дату.
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022631
Antei
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2toypaul:
Да, мне знакома Ваша проблема.

Если Вам из справочника sc656 нужно толкьо id, почему бы его не взять
из h.objid и не делать лишнюю связку?
Но, ладно, раз надо...

А 2001-08-10 20 2001-08-01 20

Чтобы получить одну строку нужно что-то вроде (работает)

select
s1id,
h1date,
h1value,
h2date,
h2value

from
(select
s.id as s1id,
h.id as h1id,
h.date as h1date,
h.value as h1value

from
_1sconst h
inner join sc656 s
on s.id = h.objid
where
date = (select max(date) from _1sconst)
and
h.id = 658
) as tab1
inner join
(select
s.id as s2id,
h.id as h2id,
h.date as h2date,
h.value as h2value

from
_1sconst h
inner join sc656 s
on s.id = h.objid
where
date = (select max(date) from _1sconst)
and
h.id = 659
) as tab2 on 1=1


Конечно, это не совсем красиво, т.к приходится повторять запрос 2 раза

Хотелось бы что-то вроде этого
(не работает)

select
(select tab1.sid from tab1 where hid=65 as sid,
(select tab1.hdate from tab1 where hid=65 as date1,
(select tab1.hvalue from tab1 where hid=65 as val1,
(select tab1.hdate from tab1 where hid=659) as date2,
(select tab1.hvalue from tab1 where hid=659) as val2

from
(select
s.id as sid,
h.id as hid,
h.date as hdate,
h.value as hvalue

from
_1sconst h
inner join sc656 s
on s.id = h.objid
where
date = (select max(date) from _1sconst)
and
h.id in (658, 659)
) as tab1

Но, к сожалению, алиас tab1 не виден во from в подзапросах
Может есть выход из положения?
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022632
Antei
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересно, куда деваются отступы?!!
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022643
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответ. Вами найдено еще одно из решений. Пока не могу оценить его эффектинвость, но похоже, что оно лучше чем то, что получил я. А именно:

SELECT s.descr,s.ID, n.sp2994, j.date_time_iddoc,
(select value
from _1sconst h
where
h.objid = s.id and h.id = 658 and
h.date =
(SELECT (max(hh.date))
FROM _1SCONST hh
WHERE (h.objid = hh.objid) and (hh.id = 65 and hh.date <= convert(datetime,left(j.DATE_TIME_IDDOC,)
)
),
(select value
from _1sconst h
where
h.objid = s.id and h.id = 659 and
h.date =
(SELECT (max(hh.date))
FROM _1SCONST hh
WHERE (h.objid = hh.objid) and (hh.id = 659) and hh.date <= convert(datetime,left(j.DATE_TIME_IDDOC,)
)
)
FROM
dt2988 n,
_1SJOURN j,
sc656 s
WHERE
s.ID = n.sp2993 and
j.IDDOC = n.IDDOC and
left(DATE_TIME_IDDOC, >= '20000810' and left(DATE_TIME_IDDOC, <= '20000820'

То есть используем подзапросы в списке SELECT. Это не очень удобно так как во-первых нужно делать еще одни SELECT, чтобы использовать агрегатные функции, а во-вторых использование таблицы _1sconst дважды в каждом позапросе не есть гуд.

Попробую ваш вариант.

З.Ы. У вас не совсем правильно написан отбор по макс. дате - в этом запросе нужно писать все условия, чтобы поиск происходил на верном интервале.
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022649
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прекрасно! Вот такой запрос уже выполняется гораздо быстрее:

select s.id,h1.date,h1.value,h2.date,h2.value
from sc656 s
left join
(
select objid,value,date from _1sconst h
where id=658 and date = (select max(date) from _1sconst hh where hh.objid=h.objid and hh.id=65
)
as h1 on s.id = h1.objid
left join
(
select objid,value,date from _1sconst h
where id=659 and date = (select max(date) from _1sconst hh where hh.objid=h.objid and hh.id=659)
)
as h2 on s.id = h2.objid
order by id

Причем можно использовать агрегатные функции. Только по-моему есть один минус - нельзя задавать ограничение по дате из другой таблицы - ее (другю талицу) в join уже никак не всунуть (может я и ошибаюсь). Но всеравно, это уже нечто!
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022658
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чего-то я никак не могу въехать - как сделать в этот (последний запрос) зависимость от еще одной таблицы.

в том запросе где ищется максимальная дата стоит еще такое условие:

date <= convert(datetime,left(j.DATE_TIME_IDDOC,)

остальные таблицы связаные между собой так:

FROM
dt2988 n (таблица расходных документов),
_1SJOURN j (таблица всех документов - здесь реквизит дата),
sc656 s (справочник товаров)
WHERE
s.ID = n.sp2993 and
j.IDDOC = n.IDDOC

Как в последний запрос в последовательность соединений вставить связь с таблицей _1sjourn так чтобы выполнялось вышеописанное условие?
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022729
Antei
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Честно, говоря не увидел проблемы, почему бы не взять те
join'ы которые у Вас были с таблицей документа dt2988 и
журналом _1SJOURN и присоединить их к Вашему новому запросу.

FROM
dt2988 n
inner join _1SJOURN j
j.IDDOC = n.IDDOC
and
left(DATE_TIME_IDDOC, >= '20000810'
and
left(DATE_TIME_IDDOC, <= '20000820'
inner join sc656 s
on s.ID = n.sp2993 and

--ну а дальше 2 join'а которые у Вас были
...

--и в условиях в подзапросах можно использовать
date <= convert(datetime,left(j.DATE_TIME_IDDOC,)

(не проверял, но должно работать)
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022785
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В том-то и дело, что так не работает. См. также ветку как соединить два подзапроса. Условие с алиасом j можно использовать в предложении ON, но в подзапросе уже нельзя
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022833
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если так:
\nselect x.date658, val658 = h658.value, x.date659, val659 = h659.value
from (
select id658 = 658
, date658 = (
select [date] = max([date])
from _1sconst
where [date] <= '20000820'
and [id] = 658
)
, id659 = 659
, date659 = (
select [date] = max([date])
from _1sconst
where [date] <= '20000820'
and [id] = 659
)
) as x
join _1sconst h658 on h658.[date] = x.date658 and h658.[id] = x.id658
join _1sconst h659 on h659.[date] = x.date659 and h659.[id] = x.id659


Таблицу sc656 прицепите сами.

PS а как у Glory отступы получаются? Так красиво было.
...
Рейтинг: 0 / 0
Как решитить такую задачу на SQL?
    #32022845
Фотография toypaul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вроде знаю что вы работали с 1С, поэтому должны понимать, что максимум даты должен находится не у всех элементов данного реквизита (а у вас именно так получается), а у конкретного элемента, конкретного реквизита. Это во-первых, во-вторых максимум должен находится не по постоянной дате, а по дате документа (из таблицы журнала). Для постоянной даты решение найдено, осталось понять как прицепить зависимость от даты в журнале документов. Единественное пока работающее решение - использование подзапросов в списке SELECT (об этом я писал на Территории 1С)
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как решитить такую задачу на SQL?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]