Select within or closest to date range MSSQL
Lets say we have a table
CREATE TABLE [dbo].[Product](
[ProductId] [int] NOT NULL,
[Name] [varchar](50) NOT NULL
)
CREATE TABLE [ProductPrice](
[ProductPriceId] [int] NOT NULL,
[ProductId] [int] NOT NULL,
[Price] [decimal](19, 4) NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NULL
)
And sample data
INSERT INTO ProductPrice
([ProductPriceId] ,[ProductId], [Price], [StartDate], [EndDate])
VALUES
( 1 ,1 , 23 , '2018-12-13' , '2018-12-27'),
( 2 ,1 , 26 , '2018-12-18' , '2018-12-20'),
( 3 ,1 , 21 , '2018-12-10' , null),
( 4 ,1 , 22 , '2018-12-28' , '2018-12-30'),
( 5 ,1 , 27 , '2019-1-01' , '2019-01-18')
;
INSERT INTO [Product]
([ProductId]
,[Name])
VALUES
(1 ,'Burger') ,
(2 ,'Coke 2L')
;
The productID is a foreign key to another table Product
this table has the prices for our products .
The question is assuming today's date is 2018-12-19 (19 Decemeber 2018)
How do we get the current price for date (2018-12-19) based on giving priority to EndDate is not null compared to the
default date were price EndDate will be null
Question 1 How do l get price trend with desired output like below based on EndDate
thus in our case the closest date based on end date is rightful order:
-1- EndDate 2018-12-20 ( 20 Decemeber 2018 ) ProductPriceID : 2 Price : 26
-2- EndDate 2018-12-27 ( 27 Decemeber 2018 ) ProductPriceID : 1 Price : 23
-3- EndDate 2018-12-30 ( 30 Decemeber 2018 ) ProductPriceID : 4 Price : 22
-4- EndDate 2019-1-01 ( 1 January 2019 ) ProductPriceID : 5 Price : 27
-5- EndDate NULL ProductPriceID : 3 Price : 21
if there is no price within range then the default is date with null field : thus [EndDate NULL ProductPriceID : 3 Price : 21]
Question 2 is How to get curret price based on EndDate the priority mentioned above
the current desired price is : 26
but however if i do this
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP (1000) [ProductPriceId]
,[ProductId]
,[Price]
,[StartDate]
,[EndDate]
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by p.[EndDate] asc
l get :
-----------------------------------------------------------------------
ProductPriceId ProductId Price StartDate EndDate
--------------------------------------------------------------------------
3 1 21.0000 2018-12-10 NULL
2 1 26.0000 2018-12-18 2018-12-19
1 1 23.0000 2018-12-13 2018-12-27
4 1 22.0000 2018-12-28 2018-12-30
5 1 27.0000 2019-01-01 2019-01-18
but however null should be at the end
Question 3 : retrieving the whole thing product list with the current price :
what l tried
/****** Script for SelectTopNRows command from SSMS ******/
;with ctaCurrentPrice As
(
-- tried gettign current price for product
SELECT *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
)
Select * ,
(
Select Top 1 Price From ctaCurrentPrice where ProductId = pro.[ProductId]
) As Price ,
(
Select Top 1 StartDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As StartDate,
(
Select Top 1 EndDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As EndDate
From Product As pro
what am getting
ProductId Name Price StartDate EndDate
1 Burger 23.0000 2018-12-13 2018-12-27
2 Coke 2L NULL NULL NULL
of which the desired is to be like
ProductId Name Price StartDate EndDate
1 Burger 26.0000 2018-12-18 2018-12-19
2 Coke 2L NULL NULL NULL
Edit 2 :
l have found the solution hope
SELECT Top 1 *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
p.[ProductId] = 1
AND
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc
sql-server select date
add a comment |
Lets say we have a table
CREATE TABLE [dbo].[Product](
[ProductId] [int] NOT NULL,
[Name] [varchar](50) NOT NULL
)
CREATE TABLE [ProductPrice](
[ProductPriceId] [int] NOT NULL,
[ProductId] [int] NOT NULL,
[Price] [decimal](19, 4) NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NULL
)
And sample data
INSERT INTO ProductPrice
([ProductPriceId] ,[ProductId], [Price], [StartDate], [EndDate])
VALUES
( 1 ,1 , 23 , '2018-12-13' , '2018-12-27'),
( 2 ,1 , 26 , '2018-12-18' , '2018-12-20'),
( 3 ,1 , 21 , '2018-12-10' , null),
( 4 ,1 , 22 , '2018-12-28' , '2018-12-30'),
( 5 ,1 , 27 , '2019-1-01' , '2019-01-18')
;
INSERT INTO [Product]
([ProductId]
,[Name])
VALUES
(1 ,'Burger') ,
(2 ,'Coke 2L')
;
The productID is a foreign key to another table Product
this table has the prices for our products .
The question is assuming today's date is 2018-12-19 (19 Decemeber 2018)
How do we get the current price for date (2018-12-19) based on giving priority to EndDate is not null compared to the
default date were price EndDate will be null
Question 1 How do l get price trend with desired output like below based on EndDate
thus in our case the closest date based on end date is rightful order:
-1- EndDate 2018-12-20 ( 20 Decemeber 2018 ) ProductPriceID : 2 Price : 26
-2- EndDate 2018-12-27 ( 27 Decemeber 2018 ) ProductPriceID : 1 Price : 23
-3- EndDate 2018-12-30 ( 30 Decemeber 2018 ) ProductPriceID : 4 Price : 22
-4- EndDate 2019-1-01 ( 1 January 2019 ) ProductPriceID : 5 Price : 27
-5- EndDate NULL ProductPriceID : 3 Price : 21
if there is no price within range then the default is date with null field : thus [EndDate NULL ProductPriceID : 3 Price : 21]
Question 2 is How to get curret price based on EndDate the priority mentioned above
the current desired price is : 26
but however if i do this
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP (1000) [ProductPriceId]
,[ProductId]
,[Price]
,[StartDate]
,[EndDate]
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by p.[EndDate] asc
l get :
-----------------------------------------------------------------------
ProductPriceId ProductId Price StartDate EndDate
--------------------------------------------------------------------------
3 1 21.0000 2018-12-10 NULL
2 1 26.0000 2018-12-18 2018-12-19
1 1 23.0000 2018-12-13 2018-12-27
4 1 22.0000 2018-12-28 2018-12-30
5 1 27.0000 2019-01-01 2019-01-18
but however null should be at the end
Question 3 : retrieving the whole thing product list with the current price :
what l tried
/****** Script for SelectTopNRows command from SSMS ******/
;with ctaCurrentPrice As
(
-- tried gettign current price for product
SELECT *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
)
Select * ,
(
Select Top 1 Price From ctaCurrentPrice where ProductId = pro.[ProductId]
) As Price ,
(
Select Top 1 StartDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As StartDate,
(
Select Top 1 EndDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As EndDate
From Product As pro
what am getting
ProductId Name Price StartDate EndDate
1 Burger 23.0000 2018-12-13 2018-12-27
2 Coke 2L NULL NULL NULL
of which the desired is to be like
ProductId Name Price StartDate EndDate
1 Burger 26.0000 2018-12-18 2018-12-19
2 Coke 2L NULL NULL NULL
Edit 2 :
l have found the solution hope
SELECT Top 1 *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
p.[ProductId] = 1
AND
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc
sql-server select date
Why are you overlapping dates?
– McNets
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago
add a comment |
Lets say we have a table
CREATE TABLE [dbo].[Product](
[ProductId] [int] NOT NULL,
[Name] [varchar](50) NOT NULL
)
CREATE TABLE [ProductPrice](
[ProductPriceId] [int] NOT NULL,
[ProductId] [int] NOT NULL,
[Price] [decimal](19, 4) NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NULL
)
And sample data
INSERT INTO ProductPrice
([ProductPriceId] ,[ProductId], [Price], [StartDate], [EndDate])
VALUES
( 1 ,1 , 23 , '2018-12-13' , '2018-12-27'),
( 2 ,1 , 26 , '2018-12-18' , '2018-12-20'),
( 3 ,1 , 21 , '2018-12-10' , null),
( 4 ,1 , 22 , '2018-12-28' , '2018-12-30'),
( 5 ,1 , 27 , '2019-1-01' , '2019-01-18')
;
INSERT INTO [Product]
([ProductId]
,[Name])
VALUES
(1 ,'Burger') ,
(2 ,'Coke 2L')
;
The productID is a foreign key to another table Product
this table has the prices for our products .
The question is assuming today's date is 2018-12-19 (19 Decemeber 2018)
How do we get the current price for date (2018-12-19) based on giving priority to EndDate is not null compared to the
default date were price EndDate will be null
Question 1 How do l get price trend with desired output like below based on EndDate
thus in our case the closest date based on end date is rightful order:
-1- EndDate 2018-12-20 ( 20 Decemeber 2018 ) ProductPriceID : 2 Price : 26
-2- EndDate 2018-12-27 ( 27 Decemeber 2018 ) ProductPriceID : 1 Price : 23
-3- EndDate 2018-12-30 ( 30 Decemeber 2018 ) ProductPriceID : 4 Price : 22
-4- EndDate 2019-1-01 ( 1 January 2019 ) ProductPriceID : 5 Price : 27
-5- EndDate NULL ProductPriceID : 3 Price : 21
if there is no price within range then the default is date with null field : thus [EndDate NULL ProductPriceID : 3 Price : 21]
Question 2 is How to get curret price based on EndDate the priority mentioned above
the current desired price is : 26
but however if i do this
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP (1000) [ProductPriceId]
,[ProductId]
,[Price]
,[StartDate]
,[EndDate]
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by p.[EndDate] asc
l get :
-----------------------------------------------------------------------
ProductPriceId ProductId Price StartDate EndDate
--------------------------------------------------------------------------
3 1 21.0000 2018-12-10 NULL
2 1 26.0000 2018-12-18 2018-12-19
1 1 23.0000 2018-12-13 2018-12-27
4 1 22.0000 2018-12-28 2018-12-30
5 1 27.0000 2019-01-01 2019-01-18
but however null should be at the end
Question 3 : retrieving the whole thing product list with the current price :
what l tried
/****** Script for SelectTopNRows command from SSMS ******/
;with ctaCurrentPrice As
(
-- tried gettign current price for product
SELECT *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
)
Select * ,
(
Select Top 1 Price From ctaCurrentPrice where ProductId = pro.[ProductId]
) As Price ,
(
Select Top 1 StartDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As StartDate,
(
Select Top 1 EndDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As EndDate
From Product As pro
what am getting
ProductId Name Price StartDate EndDate
1 Burger 23.0000 2018-12-13 2018-12-27
2 Coke 2L NULL NULL NULL
of which the desired is to be like
ProductId Name Price StartDate EndDate
1 Burger 26.0000 2018-12-18 2018-12-19
2 Coke 2L NULL NULL NULL
Edit 2 :
l have found the solution hope
SELECT Top 1 *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
p.[ProductId] = 1
AND
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc
sql-server select date
Lets say we have a table
CREATE TABLE [dbo].[Product](
[ProductId] [int] NOT NULL,
[Name] [varchar](50) NOT NULL
)
CREATE TABLE [ProductPrice](
[ProductPriceId] [int] NOT NULL,
[ProductId] [int] NOT NULL,
[Price] [decimal](19, 4) NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NULL
)
And sample data
INSERT INTO ProductPrice
([ProductPriceId] ,[ProductId], [Price], [StartDate], [EndDate])
VALUES
( 1 ,1 , 23 , '2018-12-13' , '2018-12-27'),
( 2 ,1 , 26 , '2018-12-18' , '2018-12-20'),
( 3 ,1 , 21 , '2018-12-10' , null),
( 4 ,1 , 22 , '2018-12-28' , '2018-12-30'),
( 5 ,1 , 27 , '2019-1-01' , '2019-01-18')
;
INSERT INTO [Product]
([ProductId]
,[Name])
VALUES
(1 ,'Burger') ,
(2 ,'Coke 2L')
;
The productID is a foreign key to another table Product
this table has the prices for our products .
The question is assuming today's date is 2018-12-19 (19 Decemeber 2018)
How do we get the current price for date (2018-12-19) based on giving priority to EndDate is not null compared to the
default date were price EndDate will be null
Question 1 How do l get price trend with desired output like below based on EndDate
thus in our case the closest date based on end date is rightful order:
-1- EndDate 2018-12-20 ( 20 Decemeber 2018 ) ProductPriceID : 2 Price : 26
-2- EndDate 2018-12-27 ( 27 Decemeber 2018 ) ProductPriceID : 1 Price : 23
-3- EndDate 2018-12-30 ( 30 Decemeber 2018 ) ProductPriceID : 4 Price : 22
-4- EndDate 2019-1-01 ( 1 January 2019 ) ProductPriceID : 5 Price : 27
-5- EndDate NULL ProductPriceID : 3 Price : 21
if there is no price within range then the default is date with null field : thus [EndDate NULL ProductPriceID : 3 Price : 21]
Question 2 is How to get curret price based on EndDate the priority mentioned above
the current desired price is : 26
but however if i do this
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP (1000) [ProductPriceId]
,[ProductId]
,[Price]
,[StartDate]
,[EndDate]
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by p.[EndDate] asc
l get :
-----------------------------------------------------------------------
ProductPriceId ProductId Price StartDate EndDate
--------------------------------------------------------------------------
3 1 21.0000 2018-12-10 NULL
2 1 26.0000 2018-12-18 2018-12-19
1 1 23.0000 2018-12-13 2018-12-27
4 1 22.0000 2018-12-28 2018-12-30
5 1 27.0000 2019-01-01 2019-01-18
but however null should be at the end
Question 3 : retrieving the whole thing product list with the current price :
what l tried
/****** Script for SelectTopNRows command from SSMS ******/
;with ctaCurrentPrice As
(
-- tried gettign current price for product
SELECT *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
)
Select * ,
(
Select Top 1 Price From ctaCurrentPrice where ProductId = pro.[ProductId]
) As Price ,
(
Select Top 1 StartDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As StartDate,
(
Select Top 1 EndDate From ctaCurrentPrice where ProductId = pro.[ProductId]
) As EndDate
From Product As pro
what am getting
ProductId Name Price StartDate EndDate
1 Burger 23.0000 2018-12-13 2018-12-27
2 Coke 2L NULL NULL NULL
of which the desired is to be like
ProductId Name Price StartDate EndDate
1 Burger 26.0000 2018-12-18 2018-12-19
2 Coke 2L NULL NULL NULL
Edit 2 :
l have found the solution hope
SELECT Top 1 *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
p.[ProductId] = 1
AND
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc
sql-server select date
sql-server select date
edited 1 hour ago
McNets
14.9k41857
14.9k41857
asked 4 hours ago
Billy WatsyBilly Watsy
103
103
Why are you overlapping dates?
– McNets
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago
add a comment |
Why are you overlapping dates?
– McNets
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago
Why are you overlapping dates?
– McNets
3 hours ago
Why are you overlapping dates?
– McNets
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago
add a comment |
1 Answer
1
active
oldest
votes
Question 1 How do l get price trend with desired output like below
based on EndDate
Simply use COALESCE to convert NULL date values to 31/12/9999 that is the maximum value allowed for a datetime column.
SELECT
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
ORDER BY
ProductId,
COALESCE(EndDate, '99991231');
ProductPriceId | ProductId | Price | StartDate | EndDate
-------------: | --------: | :------ | :------------------ | :------------------
2 | 1 | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
1 | 1 | 23.0000 | 13/12/2018 00:00:00 | 27/12/2018 00:00:00
4 | 1 | 22.0000 | 28/12/2018 00:00:00 | 30/12/2018 00:00:00
5 | 1 | 27.0000 | 01/01/2019 00:00:00 | 18/01/2019 00:00:00
3 | 1 | 21.0000 | 10/12/2018 00:00:00 | null
Question 2 is How to get curret price based on EndDate the priority mentioned above
Then use an OUTER APPLY join to get the first row that match the condition:
DECLARE @PriceDate datetime = '20181219';
SELECT
p.ProductId,
p.Name,
pl.Price,
pl.StartDate,
pl.EndDate
FROM
Product p
OUTER APPLY (SELECT TOP 1
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
WHERE
ProductId = p.ProductId
AND EndDate > @PriceDate
ORDER BY
ProductId,
COALESCE(EndDate, '99991231')) pl;
ProductId | Name | Price | StartDate | EndDate
--------: | :------ | :------ | :------------------ | :------------------
1 | Burger | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
2 | Coke 2L | null | null | null
db<>fiddle here
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226679%2fselect-within-or-closest-to-date-range-mssql%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Question 1 How do l get price trend with desired output like below
based on EndDate
Simply use COALESCE to convert NULL date values to 31/12/9999 that is the maximum value allowed for a datetime column.
SELECT
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
ORDER BY
ProductId,
COALESCE(EndDate, '99991231');
ProductPriceId | ProductId | Price | StartDate | EndDate
-------------: | --------: | :------ | :------------------ | :------------------
2 | 1 | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
1 | 1 | 23.0000 | 13/12/2018 00:00:00 | 27/12/2018 00:00:00
4 | 1 | 22.0000 | 28/12/2018 00:00:00 | 30/12/2018 00:00:00
5 | 1 | 27.0000 | 01/01/2019 00:00:00 | 18/01/2019 00:00:00
3 | 1 | 21.0000 | 10/12/2018 00:00:00 | null
Question 2 is How to get curret price based on EndDate the priority mentioned above
Then use an OUTER APPLY join to get the first row that match the condition:
DECLARE @PriceDate datetime = '20181219';
SELECT
p.ProductId,
p.Name,
pl.Price,
pl.StartDate,
pl.EndDate
FROM
Product p
OUTER APPLY (SELECT TOP 1
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
WHERE
ProductId = p.ProductId
AND EndDate > @PriceDate
ORDER BY
ProductId,
COALESCE(EndDate, '99991231')) pl;
ProductId | Name | Price | StartDate | EndDate
--------: | :------ | :------ | :------------------ | :------------------
1 | Burger | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
2 | Coke 2L | null | null | null
db<>fiddle here
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
add a comment |
Question 1 How do l get price trend with desired output like below
based on EndDate
Simply use COALESCE to convert NULL date values to 31/12/9999 that is the maximum value allowed for a datetime column.
SELECT
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
ORDER BY
ProductId,
COALESCE(EndDate, '99991231');
ProductPriceId | ProductId | Price | StartDate | EndDate
-------------: | --------: | :------ | :------------------ | :------------------
2 | 1 | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
1 | 1 | 23.0000 | 13/12/2018 00:00:00 | 27/12/2018 00:00:00
4 | 1 | 22.0000 | 28/12/2018 00:00:00 | 30/12/2018 00:00:00
5 | 1 | 27.0000 | 01/01/2019 00:00:00 | 18/01/2019 00:00:00
3 | 1 | 21.0000 | 10/12/2018 00:00:00 | null
Question 2 is How to get curret price based on EndDate the priority mentioned above
Then use an OUTER APPLY join to get the first row that match the condition:
DECLARE @PriceDate datetime = '20181219';
SELECT
p.ProductId,
p.Name,
pl.Price,
pl.StartDate,
pl.EndDate
FROM
Product p
OUTER APPLY (SELECT TOP 1
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
WHERE
ProductId = p.ProductId
AND EndDate > @PriceDate
ORDER BY
ProductId,
COALESCE(EndDate, '99991231')) pl;
ProductId | Name | Price | StartDate | EndDate
--------: | :------ | :------ | :------------------ | :------------------
1 | Burger | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
2 | Coke 2L | null | null | null
db<>fiddle here
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
add a comment |
Question 1 How do l get price trend with desired output like below
based on EndDate
Simply use COALESCE to convert NULL date values to 31/12/9999 that is the maximum value allowed for a datetime column.
SELECT
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
ORDER BY
ProductId,
COALESCE(EndDate, '99991231');
ProductPriceId | ProductId | Price | StartDate | EndDate
-------------: | --------: | :------ | :------------------ | :------------------
2 | 1 | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
1 | 1 | 23.0000 | 13/12/2018 00:00:00 | 27/12/2018 00:00:00
4 | 1 | 22.0000 | 28/12/2018 00:00:00 | 30/12/2018 00:00:00
5 | 1 | 27.0000 | 01/01/2019 00:00:00 | 18/01/2019 00:00:00
3 | 1 | 21.0000 | 10/12/2018 00:00:00 | null
Question 2 is How to get curret price based on EndDate the priority mentioned above
Then use an OUTER APPLY join to get the first row that match the condition:
DECLARE @PriceDate datetime = '20181219';
SELECT
p.ProductId,
p.Name,
pl.Price,
pl.StartDate,
pl.EndDate
FROM
Product p
OUTER APPLY (SELECT TOP 1
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
WHERE
ProductId = p.ProductId
AND EndDate > @PriceDate
ORDER BY
ProductId,
COALESCE(EndDate, '99991231')) pl;
ProductId | Name | Price | StartDate | EndDate
--------: | :------ | :------ | :------------------ | :------------------
1 | Burger | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
2 | Coke 2L | null | null | null
db<>fiddle here
Question 1 How do l get price trend with desired output like below
based on EndDate
Simply use COALESCE to convert NULL date values to 31/12/9999 that is the maximum value allowed for a datetime column.
SELECT
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
ORDER BY
ProductId,
COALESCE(EndDate, '99991231');
ProductPriceId | ProductId | Price | StartDate | EndDate
-------------: | --------: | :------ | :------------------ | :------------------
2 | 1 | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
1 | 1 | 23.0000 | 13/12/2018 00:00:00 | 27/12/2018 00:00:00
4 | 1 | 22.0000 | 28/12/2018 00:00:00 | 30/12/2018 00:00:00
5 | 1 | 27.0000 | 01/01/2019 00:00:00 | 18/01/2019 00:00:00
3 | 1 | 21.0000 | 10/12/2018 00:00:00 | null
Question 2 is How to get curret price based on EndDate the priority mentioned above
Then use an OUTER APPLY join to get the first row that match the condition:
DECLARE @PriceDate datetime = '20181219';
SELECT
p.ProductId,
p.Name,
pl.Price,
pl.StartDate,
pl.EndDate
FROM
Product p
OUTER APPLY (SELECT TOP 1
ProductPriceId,
ProductId,
Price,
StartDate,
EndDate
FROM
ProductPrice
WHERE
ProductId = p.ProductId
AND EndDate > @PriceDate
ORDER BY
ProductId,
COALESCE(EndDate, '99991231')) pl;
ProductId | Name | Price | StartDate | EndDate
--------: | :------ | :------ | :------------------ | :------------------
1 | Burger | 26.0000 | 18/12/2018 00:00:00 | 20/12/2018 00:00:00
2 | Coke 2L | null | null | null
db<>fiddle here
edited 1 hour ago
answered 1 hour ago
McNetsMcNets
14.9k41857
14.9k41857
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
add a comment |
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
l tested your query its simple & works , thanks
– Billy Watsy
1 hour ago
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226679%2fselect-within-or-closest-to-date-range-mssql%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Why are you overlapping dates?
– McNets
3 hours ago
@McNets l was given the data as is my task is to retrieve the price based on the closest price to EndDate
– Billy Watsy
3 hours ago