In SQL 2005 stored proc I need to run a query that contains a 1-M. I need to return only 1 of the Many table the one with the earliest date.
I have looked at In SQL how do I write a query to return 1 record from a 1 to many relationship?
and SQL conundrum, how to select latest date for part, but only 1 row per part (unique)
But I am not sure what's the best solution in my case as I am also doing a Insert Into temp table and using dynamic sorting and paging.
Here is my SQL. What I want is to return many rows of Foo, but only the earliest b.CreatedDate between the start and end data paramaters I pass in where there is normally about 5 rows in Bar for each Foo.
DECLARE @StartDate datetime
DECLARE @EndDate datetime
INSERT INTO @Results
SELECT distinct
f.Name,
f.Price
b.CreatedDate ,
// loads more columns removed for brevity
FROM
foo f
join bar b on f.Id = b.fooId
// loads more table removed 开发者_如何转开发for brevity
WHERE
(@x is null OR f.Id = @x)
AND (@Deal is null OR f.IsDeal = @Deal)
AND (@StartDate is null OR sd.SailingDate >= @StartDate)
AND (@EndDate is null OR sd.SailingDate <= @EndDate)
// loads more filters removed for brevity
declare @firstResult int, @lastResult int
set @firstResult = ((@PageNumber-1) * @ItemsPerPage) + 1;
set @lastResult = @firstResult + @ItemsPerPage;
select @TotalResults = count(1) from @Results;
WITH ResultItems AS
(
SELECT *, ROW_NUMBER() OVER (
ORDER BY
CASE WHEN @SortBy = 'priceLow' THEN Price END ASC,
CASE WHEN @SortBy = 'Soonest' THEN CreatedDate END ASC,
CASE WHEN @SortBy = 'priceHigh' THEN Price END DESC
) As RowNumber
FROM @Results r
)
SELECT * from ResultItems
WHERE RowNumber >= @firstResult AND RowNumber < @lastResult
ORDER BY
CASE
WHEN @SortBy = 'priceHigh' THEN (RANK() OVER (ORDER BY Price desc))
WHEN @SortBy = 'priceLow' THEN (RANK() OVER (ORDER BY Price))
WHEN @SortBy = 'Soonest' THEN (RANK() OVER (ORDER BY CreatedDate ))
END
This query as is will return multiple 'b.CreatedDate' instead of just the earliest one between my Filters
Update So I want to See If my source data is:
Foo
___
1 , Hello
2 , There
Boo
___
1, 1, 2011-2-4
2, 1, 2011-3-6
3, 1, 2012-12-21
4, 2, 2012-11-2
The result would be
1, Hello,2011-2-4
2, There, 2012-11-2
I think I just got it working by adding a CTE to the top of my query
;with cteMinDate as (
select FooId, min(CreatedDate) As CreatedDate
from Bar WHERE
(@StartDate is null OR CreatedDate>= @StartDate)
AND (@EndDate is null OR CreatedDate<= @EndDate)
group by FooId
)
Same as shown here SQL conundrum, how to select latest date for part, but only 1 row per part (unique). Doing this allows me to remove the date query part from my main query and only do it once in the CTE
精彩评论