Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как решитить такую задачу на SQL? / 12 сообщений из 12, страница 1 из 1
10.02.2002, 17:31
    #32022592
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
С помощью такого запроса:

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
10.02.2002, 19:24
    #32022595
©+Vintik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Думается мне что нужно выборку надо делать из трёх таблиц
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
11.02.2002, 06:31
    #32022606
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Если твой запрос это конечный вариант, то это не совсем то что нужно. В результате не должно быть повторяющихся строка с ключом a.id, в каждой из колонок (date1,val1) - date1 должна быть максимальной в пределах ключа, а val1 должно быть значением из этой строки (где дата максимальна). Вот так. Какие еще будут идеи?

Ты сам с 1С случайно не работаешь? Если работаешь, то наверно тебе знакома эта задача - выборка у справочника более чем двух периодических реквизитов на определенную дату.
...
Рейтинг: 0 / 0
11.02.2002, 09:30
    #32022631
Antei
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
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
11.02.2002, 09:32
    #32022632
Antei
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Интересно, куда деваются отступы?!!
...
Рейтинг: 0 / 0
11.02.2002, 11:24
    #32022643
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Спасибо за ответ. Вами найдено еще одно из решений. Пока не могу оценить его эффектинвость, но похоже, что оно лучше чем то, что получил я. А именно:

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
11.02.2002, 11:50
    #32022649
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Прекрасно! Вот такой запрос уже выполняется гораздо быстрее:

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
11.02.2002, 12:29
    #32022658
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Чего-то я никак не могу въехать - как сделать в этот (последний запрос) зависимость от еще одной таблицы.

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

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
12.02.2002, 09:31
    #32022729
Antei
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Честно, говоря не увидел проблемы, почему бы не взять те
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
12.02.2002, 15:58
    #32022785
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
В том-то и дело, что так не работает. См. также ветку как соединить два подзапроса. Условие с алиасом j можно использовать в предложении ON, но в подзапросе уже нельзя
...
Рейтинг: 0 / 0
13.02.2002, 07:44
    #32022833
MadDog
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
А если так:
\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
13.02.2002, 08:42
    #32022845
toypaul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как решитить такую задачу на SQL?
Я вроде знаю что вы работали с 1С, поэтому должны понимать, что максимум даты должен находится не у всех элементов данного реквизита (а у вас именно так получается), а у конкретного элемента, конкретного реквизита. Это во-первых, во-вторых максимум должен находится не по постоянной дате, а по дате документа (из таблицы журнала). Для постоянной даты решение найдено, осталось понять как прицепить зависимость от даты в журнале документов. Единественное пока работающее решение - использование подзапросов в списке SELECT (об этом я писал на Территории 1С)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как решитить такую задачу на SQL? / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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