Stack Overflow на русском Asked on November 30, 2021
Вот минимально воспроизводимый пример, допустим я хочу узнать последние цены, но на определённую дату
Сейчас я делаю так, но это не красиво, и ресурсоёмко наверняка, конвертировать все поля
CREATE TABLE [dbo].[Test](
[OtherID] [int] NOT NULL,
[SomeDate] [date] NOT NULL,
[Price] [real] NOT NULL
)
insert into Test values
(1,'01.01.2010',50),
(1,'02.01.2010',100),
(1,'01.01.2011',200),
(2,'01.01.2010',150),
(2,'01.02.2010',300),
(3,'01.03.2010',15),
(3,'01.02.2012',55)
declare @Date date
Set @Date='2010-07-04'
SELECT * from Test where (CAST([SomeDate]as char)+CAST([OtherID] as char))
IN(
SELECT CAST(MAX([SomeDate])as char)+CAST([OtherID] as char) FROM dbo.Test
WHERE @Date<=[SomeDate]
GROUP BY [OtherID]
)
А хотелось бы так
declare @Date date
Set @Date='2010-07-04'
SELECT * from Test where ([SomeDate],[OtherID])
IN(
SELECT MAX([SomeDate]),[OtherID] FROM dbo.Test
WHERE @Date<=[SomeDate]
GROUP BY [OtherID]
)
Гугл говорит что у MY-SQL с этим нет проблем, а что насчёт T-SQL ?
P.S. своей ID у таблицы нет и добавить нельзя, иначе было бы куда проще
Я не понимаю зачем так усложнять когда есть оконные функции, я рекомендую познакомиться с ними получше, так как они облегчают сложные запросы типа таких.
WITH [Data] AS (
SELECT
*,
ROW_NUMBER() over (partition by [OtherID] order by [SomeDate] desc) AS ROW_NUMBER
FROM Test
WHERE @Date <= [SomeDate]
)
SELECT
[Data].*
FROM [Data]
WHERE
ROW_NUMBER = 1;
не нужно ничего конвертировать просто пронумеровать по группе отсортировать и вывести первую. Ссылка на фидл
послесловие.
условие типа
([SomeDate],[OtherID])
IN(
SELECT MAX([SomeDate]),[OtherID] FROM dbo.Test
WHERE @Date<=[SomeDate]
GROUP BY [OtherID]
)
не гарантирует желаемый ответ в случае если у вас на один день несколько цен и это место потенциальной ошибки.
Answered by Aziz Umarov on November 30, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP