2011-02-07 2 views
0

방문SQL Server에 아래 표시된 결과를 얻기 위해 다음 2 개의 테이블을 연결하는 방법은 무엇입니까? (계속)

LoginID, StaffName, qno, trackno, tmstamp, Service 
1,  James,  1001, 1,  01-01-2011, No1  (transfer to No2) 
2,  John,  1002, 2,  01-01-2011, No1 
2,  John,  1003, 3,  01-01-2011, No1 
1,  James,  1001, 1,  01-01-2011, No2  (transfered from No1) 
2,  James,  1003, 3,  01-01-2011, No1  (recall the queue no) 

물질

content, trackno, tmstamp 
001,  1,  01-01-2011 
002,  1,  01-01-2011 
001,  2,  01-01-2011 
002,  2,  01-01-2011 
003,  2,  01-01-2011 
001,  3,  01-01-2011 
001,  1,  01-01-2011 
001,  3,  01-01-2011 
002,  3,  01-01-2011 

결과

StaffName, tmstamp, noOfQno, noOfContent 
James,  01-01-2011, 3,  5 
John,  01-01-2011, 2,  4 

은 이미이 질문을했다. (.이 질문에 대한 유사)

how to link the following 2 tables to get the result which is shown below in SQL Server?`

그리고 정답은 이미 존재한다.

SELECT StaffName, tmstamp, noOfQno, noOfContent 
    FROM (
       SELECT StaffName, tmstamp, trackno, COUNT(1) noOfQno 
        FROM Visit 
       GROUP BY StaffName, tmstamp, trackno 
      ) a LEFT JOIN 
      (
       SELECT trackno, COUNT(1) noOfContent 
        FROM Matter 
       GROUP BY trackno 
      ) b 
    ON b.trackno = a.trackno 

하지만 그 대답에 따르면 대답은 약간 잘못되었습니다. Visit 테이블의 line 1를 들어, noOfContenct이 BE2해야하며 Visitline 4를 들어, noOfContent이어야

때문에

나는 그 대답은에 따라 얻을 것이다 결과는 ..

Result 
StaffName, tmstamp, noOfQno, noOfContent 
James,  01-01-2011, 3,  6 
John,  01-01-2011, 2,  6 

즉 1. 그래서, 3입니다.

그러나 그 대답에 따르면 : line 1, noOfContent은 3이고, line 4도 3입니다. 그러면 총 값은 6이됩니다.

그래서이 문장을 업데이트하는 방법을 묻습니다.

P. 그 진술은 그 결과와 같이 총을주지 않을 것이다. 대신 줄 단위로 값을 줄 것입니다.

+0

'물질'의 기본 키는 무엇입니까? 따라서 '방문'의 외래 키는 무엇인가? 내가 옳은 대답에 딱 맞는 솔루션을 게시 할 수있을 것 같지만 여기에는 디자인에 심각한 결함이있는 것으로 보입니다. 'Matter'의 7 번 줄은 1 번 줄과 아무런 차이가 없습니다. 어떻게 구별해야합니까? –

+0

예. 테이블에는 키가 없습니다. 예, 기본적으로 동일합니다. 그래서 차별화 할 방법을 모릅니다. – william

답변

1

당신은 당신이 가지고있는 테이블에 원하는 작업을 수행 할 수 없습니다.내가 올바르게 이해하면 방문의 1 행이 Matter 행의 1 행 2에 링크되고 방문 행 4가 Matter 행 7에 링크되어 noOfContent가 3과 같음을 의미합니다.

유일한 필드 당신은 테이블 사이에 링크가 trackno이며 그것을 사용하여 3 행을 방문에서 행 1과 행 7에 대한 3 행 noOfContent 6 그래서 3 행을 것입니다.

그것은 tmstamp 필드에 연결할 수 있습니다 연결되어야하는 행에 대해 방문 및 물질에서 동일합니다. 사실인지 확인하려면 실제 데이터를 확인해야합니다.

이 질문에 대한 올바른 대답은 테이블 구조를 재 설계하고 방문에서 기본 키를 식별하고 이것을 Matter의 외래 키로 추가해야한다는 것입니다.

편집 1 Crimsonland 주어진 대답 때문에 trackno 열에서 하나 개의 값이 다른 StaffName 재사용 할 수 없다는 전제의 정확한 결과를 제공한다. 귀하의 데이터에서 trackno 1은 John에 속하고 trackno 2와 3은 James에 속한 것 같습니다. 이 경우 해당 쿼리가 작동합니다.

편집 2 다음은 tmstamp를 사용하여 어떤 Matter가 어떤 방문과 관련되는지 파악하는 버전입니다. Matter.tmstamp가 연결된 행의 Visit.tmstamp보다 큰 것으로 가정하고 Visit의 한 행에 대해 Matter의 마지막으로 삽입 된 행에 Visit의 다음 tmstamp 값보다 작은 tmstamp 값이 있다고 가정합니다.

declare @Visit table 
(
    LoginID int, 
    StaffName varchar(50), 
    qno int, 
    trackno int, 
    tmstamp datetime, 
    [Service] char(3) 
) 

declare @Matter table 
(
    content int, 
    trackno int, 
    tmstamp datetime 
) 

insert into @Visit values (1, 'James', 1001, 1, '2011-01-01 00:00:00', 'No1') 
insert into @Visit values (2, 'John', 1002, 2, '2011-01-01 00:00:10', 'No1') 
insert into @Visit values (2, 'John', 1003, 3, '2011-01-01 00:00:20', 'No1') 
insert into @Visit values (1, 'James', 1001, 1, '2011-01-01 00:00:30', 'No2') 
insert into @Visit values (2, 'James', 1003, 3, '2011-01-01 00:00:40', 'No1') 

insert into @Matter values (001, 1, '2011-01-01 00:00:01') 
insert into @Matter values (002, 1, '2011-01-01 00:00:02') 
insert into @Matter values (001, 2, '2011-01-01 00:00:11') 
insert into @Matter values (002, 2, '2011-01-01 00:00:12') 
insert into @Matter values (003, 2, '2011-01-01 00:00:13') 
insert into @Matter values (001, 3, '2011-01-01 00:00:21') 
insert into @Matter values (001, 1, '2011-01-01 00:00:31') 
insert into @Matter values (001, 3, '2011-01-01 00:00:41') 
insert into @Matter values (002, 3, '2011-01-01 00:00:42') 

;with cteVisit 
as 
(
    select 
    StaffName, 
    qno, 
    trackno, 
    tmstamp as VisitStart, 
    (select coalesce(min(tmstamp), GetDate()) 
    from @Visit as V2 
    where V2.tmstamp > V1.tmstamp) as VisitStop 
    from @Visit as V1 
) 
select 
    V.StaffName, 
    max(VisitStart) as tmstamp, 
    (select count(*) 
    from cteVisit as V2 
    where V2.StaffName = V.StaffName) as noOfQno, 
    (select count(*) 
    from @Matter as M 
    inner join cteVisit V3 
     on M.tmstamp >= V3.VisitStart and 
     M.tmstamp < V3.VisitStop 
    where V3.StaffName = V.StaffName) as noOfQno 
from cteVisit as V 
group by StaffName 

결과

StaffName tmstamp     noOfQno noOfQno 
James  2011-01-01 00:00:40.000 3  5 
John  2011-01-01 00:00:20.000 2  4 
+0

네, 당신은 절대적으로 옳습니다 !! 그러나 문제는 .. 데이터베이스가 제 것이 아니며 재 설계가 불가능하다는 것입니다. 'tmstamp'에 대해서, 행이 삽입되는 시간을 기록하고 있습니다. 그래서. 오후 3시에 '방문'의 '1 호선'이 삽입되고 '3.05 오후'에 '사안'의 '1 호선'이 삽입 될 수있다. 그리고 'Matter'의 'Line 2'는 5 분 후에 나타날 수 있습니다. – william

+0

불행히도, 그렇지 않습니다. – william

+0

@william - tmstamp를 사용하여 수행 할 작업을 파악하는 쿼리를 게시했습니다. 그것은 당신을 위해 일할 수도 있습니다. 그것은 tmstamp 필드의 값에 의존합니다. –

1

시험해보십시오.

예제의 정확한 데이터로 견본 테이블을 만듭니다. 그것을 바탕으로 나는 당신의 쿼리를 테스트하고 이것을 생각해 냈습니다.

1 쿼리 : StaffName, tmstamp BY 방문 그룹에서 SELECT StaffName, tmstamp, trackno, COUNT (1) noOfQno , trackno

StaffName tmstamp trackno noOfQno 
James 01-01-2011 1 2 
John 01-01-2011 2 1 
John 01-01-2011 3 2 

2 검색어 : SELECT trackno, COUNT (1) noOfContent trackno

trackno noOfContent 
1 3 
2 3 
3 3 

BY 물질 그룹에서 가입 :

SELECT StaffName, tmstamp, SUM(noOfQno) asnoOfQno ,SUM(noOfContent) as noOfContent 
    FROM (
       SELECT StaffName, tmstamp, trackno, COUNT(1) noOfQno 
        FROM Visit 
       GROUP BY StaffName, tmstamp, trackno 
      ) a LEFT JOIN 
      (
       SELECT trackno, COUNT(1) noOfContent 
        FROM Matter 
       GROUP BY trackno 
      ) b 
    ON b.trackno = a.trackno 
    group by StaffName, tmstamp 

결과 :

StaffName tmstamp noofQno noofContent 
James 01-01-2011 2 3 
John 01-01-2011 3 6 

감사

+0

다시 확인할 수 있습니까? 그냥 합계와 그룹을 쿼리에 추가하십시오. – Crimsonland

+0

@william : 우리가 제공 한 샘플 테이블에서 * 작동합니다. 나는 방금 Crimsonland 's와 완전히 동일하다는 것을 알기 위해 나의 해결책을 게시했다, 그래서 나의 것은 이제 삭제되고 이것은 upvoted된다. –

+0

예. 나는 aldy를 시도했다. 같은 결과. – william

0

나는 타임 스탬프에 합류에 대해 완전히 확실하지 않다.

Nº 트랙에서 Matter 방문을 허용하고 CASE WHEN ... ELSE .... 구조를 사용할 수 있습니다. 이 같은 (이것은 올바른 SQL 코드가 아닙니다)

SELECT StaffName, tmstamp, 
    SUM(CASE WHEN qno IS NOT NULL THEN 1 ELSE 0) AS noOfQno, 
    SUM(CASE WHEN content IS NOT NULL THEN 1 ELSE 0) AS noOfContent 
    FROM Visit LEFT JOIN Matter 
    ON Visit.trackno = Matter.trackno 
GROUP BY StaffName, tmstamp 

다시 말하면 완벽한 코드! 그러나 그것은 필수적인 아이디어입니다.

희망 하시겠습니까?

관련 문제