2014-10-09 1 views
0

저는 여기서 벗어나는 방법이라고 생각하지만 최선의 방법은 확실하지 않습니다. 제품 테이블과 예약 테이블이 있습니다. 특정 시간대에 대한 예약을 기반으로 제품의 가용성을 즉시 평가해야합니다. 각 제품에 대해 여러 예약이있을 수 있지만 결과는 가용성을위한 계산 된 열이있는 제품 테이블이어야합니다. 여기에 내가 지금까지 가지고있는 것이 있지만 왼쪽 외부 조인은 내가 필요로하는 것이 아니다. 저의 진술과 함께 더 나은 접근법이 있고 결합을 제거 할 것이라고 확신합니다. 좋아요 것SQL 왼쪽 결합 및 계산 된 열이 원하는 결과를 생성하지 않음

CREATE FUNCTION [dbo].[GetAvailableReservations] 
(  
    @StartDate DateTime, 
    @EndDate DateTime 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT p.*, 
     CASE 
      WHEN r.Status = 'Active' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate 
       THEN 'Reserved' 
      WHEN r.Status = 'Primary' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate 
       THEN 'Sold' 
      WHEN r.Status = 'Primary' AND r.StartDate >= DATEADD(YY,-1,GETDATE()) AND r.EndDate <= GETDATE() 
       THEN 'Refused' 
      WHEN EXISTS (SELECT * FROM dbo.URL u WHERE u.URL = p.URL AND u.Date < DATEADD(YY,-2,GETDATE())) 
       THEN 'Needs Review' 
      ELSE 
       'Available' 
     END AS Availability 
    FROM dbo.Product AS p 
    LEFT JOIN dbo.Reservation AS r 
    ON p.Name = r.Title 
) 

는 LINQ - 투 - SQL에서 호출 할 수있는 기능이 될 후 나는 그들의 가용성 제품 목록 떨어져 조회 할 수 있습니다.

편집 - 다음은 몇 가지 샘플 데이터입니다.

Products: 
Name URL       Cost 
------------------------------------------- 
Gears http://www.gearfinder.com 250 
Shocks http://www.shockfinder.com 110 
Bolts http://www.boltfinder.com 5 



Reservations: 
Title Status  StartDate  EndDate 
---------------------------------------------- 
Gears Active  2012-01-01 2012-12-31 
Gears Primary  2012-01-01 2012-12-31 
Gears Inactive  2012-01-01 2012-12-31 
Bolts Inactive  2011-01-01 2011-12-31 
Bolts Active  2013-01-01 2013-12-31 
Bolts Primary  2014-01-01 2014-12-31 

URLs: 
URL       Date 
-------------------------------------- 
http://www.shockfinder.com 2010-01-01 
+0

무엇이 질문입니까? LINQ-to-SQL로 UDF를 호출하는 방법을 모르십니까? 당신은별로 구체적이지 않습니다. –

+0

제 질문은 함수 자체와 조인 및 case 문이 즉시 열을 계산하기위한 최선의 방법인지 여부입니다. 나는 왜 내가이 접근법을 처음부터 취하고 있는지에 대한 전반적인 설명을하기를 원했다. –

답변

0

당신은 제품 당 9 개 이상 상태 기대하지 않는 경우는, 작동 할 수 있습니다 : 당신이 다음 사용할 수있는 0의 점수를 얻을 경우

SELECT p.name, SUM(CASE WHEN r.Status = 'Active' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate THEN 10000 WHEN r.Status = 'Primary' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate THEN 1000 WHEN r.Status = 'Primary' AND r.StartDate >= DATEADD(YY,-1,GETDATE()) AND r.EndDate <= GETDATE() THEN 100 WHEN EXISTS (SELECT * FROM dbo.URL u WHERE u.URL = p.URL AND u.Date < DATEADD(YY,-2,GETDATE())) THEN 10 ELSE 0 END) AS Availability FROM dbo.Product AS p LEFT JOIN dbo.Reservation AS r ON p.Name = r.Title GROUP BY p.name

합니다. 10210과 같은 점수는 1 예약, 0 판매, 2 거부 및 1 검토 필요를 의미합니다. 샘플 데이터 세트를 제공 할 수 있다면 우리는이 쿼리를 약간 개선 할 수있을 것입니다. 쿼리 된 시간 프레임에 대해 p.name에 대해 하나 이상의 상태가 9 개 이상있을 수있는 경우에는 작동하지 않습니다.

또 다른 옵션은, 그 자체가 열에 모든 상태를 배치 :

SELECT p.name, SUM(CASE WHEN r.Status = 'Active' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate THEN 1 ELSE 0 END) AS 'Reserved', SUM(CASE WHEN r.Status = 'Primary' AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate THEN 1 ELSE 0 END) AS 'Sold', SUM(CASE WHEN r.Status = 'Primary' AND r.StartDate >= DATEADD(YY,-1,GETDATE()) AND r.EndDate <= GETDATE() THEN 1 ELSE 0 END) AS 'Refused', SUM(CASE WHEN EXISTS (SELECT * FROM dbo.URL u WHERE u.URL = p.URL AND u.Date < DATEADD(YY,-2,GETDATE())) THEN 1 ELSE 0 END) AS 'Needs Review', Count(*) AS 'Total Recs' FROM dbo.Product AS p LEFT JOIN dbo.Reservation AS r ON p.Name = r.Title GROUP BY p.name

이는 관계없이 각각에 대해 얼마나 많은 종류의 당신에게 모든 상태의 수를 제공해야합니다.

+0

다음 오류가 계속 발생합니다. ** 집계 또는 하위 쿼리가 포함 된 식에서 집계 함수를 수행 할 수 없습니다 **. 내 최종 결과를 제품 테이블 + 가용성 열로보고 싶습니다. 이 방법은 내 코드 (linq-to-SQL)에서 호출 할 수 있으며 쿼리를 실행하고 표에 바인딩합니다. –

+0

쿼리의 논리는 해당 제품이 예약 테이블에 있는지 확인하고, 그렇다면 예약 상태가 날짜 범위에 대해 _ 활성 _인지 확인해야합니다. 그렇다면 가용성이 우선시됩니다. 그렇지 않은 경우 예약 상태를 확인하여 날짜 범위의 _Primary_인지 확인합니다. 예약 테이블에없는 경우 URL 테이블에서 URL의 날짜를 확인합니다 (2 년 이상 경과 한 경우 가용성이 필요함). 리뷰_. 마지막으로, 이들 중 어느 것도 해당하지 않으면 해당 제품은 _ 사용 가능 _입니다. –

0

잘 작동합니다. 그것이 얼마나 최적인지에 관해 확실하지 않은.

SELECT p.*, 
    CASE 
     WHEN 'Active' IN (SELECT r.Status FROM dbo.Reservation r WHERE r.Title = p.Name AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate) 
      THEN 'Reserved' 
     WHEN 'Primary' IN (SELECT r.Status FROM dbo.Reservation r WHERE r.Title = p.Name AND r.StartDate >= @StartDate AND r.EndDate <= @EndDate) 
      THEN 'Sold' 
     WHEN 'Primary' IN (SELECT r.Status FROM dbo.Reservation r WHERE r.Title = p.Name AND r.StartDate >= DATEADD(YY,-1,GETDATE()) AND r.EndDate <= GETDATE()) 
      THEN 'Refused' 
     WHEN EXISTS (SELECT * FROM dbo.URL u WHERE u.URL = p.URL AND u.Date < DATEADD(YY,-2,GETDATE())) 
      THEN 'Needs Review' 
     ELSE 
      'Available' 
    END Availability 
FROM dbo.Product AS p