Sql

2009-03-23 4 views
1

을 사용하여 데이터베이스 쿼리를위한 통합 레코드 레코드에 "Urgent"속성이있는 경우 기본 값은 긴급 열에 특성 값이 표시되어야한다는 것입니다. 레코드의 속성 값이 "닫힘"이면 속성 값이 "닫힌"열에 표시되어야합니다.Sql

아래 질문이 있습니다. 내 문제는 내가 돌아오고있는 결과 중 동일한 RequesterID ("긴급"열과 "닫힌"열에 유효한 값이있는 레코드)가 두 개인 레코드가 있다는 것입니다. 내 문제는 이들이 필요하다는 것입니다. 두 개의 특정 레코드가 하나의 레코드로 표시됩니다.

아이디어가 있으십니까? 당신은 당신의 서브 요청에 가입해야합니다

SELECT DISTINCT 
    r.RequesterID, 
    sr.ModifiedDate, 
    p.FirstName + ' ' + p.LastName AS RequesterName, 
    CASE 
    WHEN sa.Attribute = 'Urgent' THEN sa.AttributeValue 
    ELSE NULL 
    END AS Urgent, 
    CASE 
    WHEN sa.Attribute = 'Closed' THEN sa.AttributeValue 
    ELSE NULL 
    END AS Closed 
FROM 
    Requester AS r 
    INNER JOIN SubRequester AS sr 
    ON r.RequesterID = sr.RequesterID 
    INNER JOIN SubRequesterAttribute AS sa 
    ON sr.SubRequesterID = sa.SubRequesterID 
    CROSS JOIN Personnel AS p 
WHERE 
    (r.UserID = p.ContractorID 
    OR r.UserID = p.EmployeeID) 
    AND 
    (sa.Attribute IN ('Urgent', 'Closed')) 
GROUP BY r.RequesterID, sr.ModifiedDate, p.FirstName, p.LastName, 
    sa.Attribute, sa.AttributeValue 
+0

많은 편집이 있습니다. 그 중 일부를 clobbering해서 죄송합니다. SQL을 형식화해야했습니다. – Welbog

답변

3

두 번 쿼리에 테이블 때문이다. Urgent의 속성 하나와 Close의 속성을 가진 속성

null이 될 수있는 인스턴스의 경우 LEFT 조인을 수행 한 다음 SELECT의 각 테이블을 참조하여 관련 속성을 표시해야합니다.

또한 크로스 조인을 권장하지 않습니다. WHERE 절에서 교차 조인 및 필터링을 수행하는 대신 FROM 절의 personnel 테이블에서 "OR"조인을 수행해야합니다.

편집 : 죄송합니다. 첫 번째 응답이 조금 급하게 이루어졌습니다. 이제 더 볼 기회가있었습니다. 서브 리퀘 스터와 서브 리퀘 스터 속성이 둘 다 중복되어 있으므로 둘 다 하위 쿼리로 분할해야합니다. 또한 두 날짜의 수정 날짜가 다를 수 있습니다. 그래서 나는 그것을 두 배로 늘 렸습니다. 이것은 완전히 테스트되지 않았으며 절대로 "최적의"솔루션입니다. 확인할 데이터베이스가없는 쿼리를 작성하는 것은 매우 까다 롭습니다. 잘만되면 그것은 내가 의미했던 것을 설명 할 것이다.

SELECT 
    r.RequesterID, 
    p.FirstName + ' ' + p.LastName AS RequesterName, 
    sra1.ModifiedDate as UrgentModifiedDate, 
    sra1.AttributeValue as Urgent, 
    sra2.ModifiedDate as ClosedModifiedDate, 
    sra2.AttributeValue as Closed 
FROM 
    Personnel AS p 
INNER JOIN 
    Requester AS r 
ON 
(
    r.UserID = p.ContractorID 
OR 
    r.UserID = p.EmployeeID 
) 
LEFT OUTER JOIN 
(
    SELECT 
     sr1.RequesterID, 
     sr1.ModifiedDate, 
     sa1.Attribute, 
     sa1.AttributeValue 
    FROM 
     SubRequester AS sr1 
    INNER JOIN 
     SubRequesterAttribute AS sa1 
    ON 
     sr1.SubRequesterID = sa1.SubRequesterID 
    AND 
     sa1.Attribute = 'Urgent' 
) sra1 
ON 
    sra1.RequesterID = r.RequesterID 
LEFT OUTER JOIN 
(
    SELECT 
     sr2.RequesterID, 
     sr2.ModifiedDate, 
     sa2.Attribute, 
     sa2.AttributeValue 
    FROM 
     SubRequester AS sr2 
    INNER JOIN 
     SubRequesterAttribute AS sa2 
    ON 
     sr2.SubRequesterID = sa2.SubRequesterID 
    AND 
     sa2.Attribute = 'Closed' 
) sra1 
ON 
    sra2.RequesterID = r.RequesterID 

SECOND 편집 : 내 마지막 편집 모든 SubRequesters 두와 관계있는 특성을 보여주고 싶은 마지막 코멘트에서 여러 SubRequesters뿐만 아니라 여러 특성이 있다고했다? 다음과 같이이 작업을 수행 할 수 있습니다.

SELECT 
    r.RequesterID, 
    p.FirstName + ' ' + p.LastName AS RequesterName, 
    sr.ModifiedDate, 
    sa1.AttributeValue as Urgent, 
    sa2.AttributeValue as Closed 
FROM 
    Personnel AS p 
INNER JOIN 
    Requester AS r 
ON 
(
    r.UserID = p.ContractorID 
OR 
    r.UserID = p.EmployeeID 
) 
INNER JOI N 
    SubRequester as sr 
ON 
    sr.RequesterID = r.RequesterID 
LEFT OUTER JOIN 
    SubRequesterAttribute AS sa1 
ON 
    sa1.SubRequesterID = sr.SubRequesterID 
AND 
    sa1.Attribute = 'Urgent' 
LEFT OUTER JOIN 
    SubRequesterAttribute AS sa2 
ON 
    sa2.SubRequesterID = sr.SubRequesterID 
AND 
    sa2.Attribute = 'Closed' 
+0

첫 번째 및 세 번째 단락을 이해합니다. 그러나 나는 두 번째 단락에서 길을 잃는다. 좀 더 자세히 설명해 주시겠습니까? – Csharp

+0

왜 "sra1.ModifiedDate as UrgentModifiedDate"를 만들고 "sra2.ModifiedDate as ClosedModifiedDate"를 만들었습니까? 날짜 필드에는 하나의 열만 있습니다. – Csharp

0

일반적으로 행이 여러 개인 경우 하나의 행으로 축소하려면 GROUP BY를 사용하는 것이 좋습니다. 당신이 그 방향으로 가려고했지만 꽤 빠져 나간 것처럼 보입니다. 행 사이에 중복되는 식으로 그룹화하고 NULL 값을 제거하는 다른 식에 그룹 함수를 적용합니다. 아래 예제에서 MIN을 사용했지만 MAX를 쉽게 사용할 수 있습니다. 요점은 그 행에 기껏해야 하나의 행에 값이 있기 때문에 그 값은 최소값과 최대 값입니다.

SELECT 
    r.RequesterID, 
    sr.ModifiedDate, 
    p.FirstName + ' ' + p.LastName AS RequesterName, 
    MIN(
    CASE 
    WHEN sa.Attribute = 'Urgent' THEN sa.AttributeValue 
    ELSE NULL 
    END 
    ) AS Urgent, 
    MIN(
    CASE 
    WHEN sa.Attribute = 'Closed' THEN sa.AttributeValue 
    ELSE NULL 
    END 
    ) AS Closed 
FROM 
    Requester AS r 
    INNER JOIN SubRequester AS sr 
    ON r.RequesterID = sr.RequesterID 
    INNER JOIN SubRequesterAttribute AS sa 
    ON sr.SubRequesterID = sa.SubRequesterID 
    CROSS JOIN Personnel AS p 
WHERE 
    (r.UserID = p.ContractorID 
    OR r.UserID = p.EmployeeID) 
    AND 
    (sa.Attribute IN ('Urgent', 'Closed')) 
GROUP BY r.RequesterID, sr.ModifiedDate, p.FirstName + ' ' + p.LastName