2011-02-07 7 views
0

訪問次の2つのテーブルをリンクして、SQL Serverに以下のような結果を得るにはどうすればよいですか? (続き)

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 

しかし、その答えによれば、答えは少し間違っています。私はその答えに応じて取得します

結果ます。..

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

noOfContenctVisitテーブルのline 1については

BE2とVisitline 4ため、noOfContentがあるべきはずだからですしたがって、全体的には、3。

しかし、その答えによると:line 1の場合、noOfContentは3であり、 line 4についても3.合計値は6になります。

この文を更新する方法を尋ねます。

P.S.その声明は結果のように合計を与えることはありません。代わりに、行単位の値を与えます。

+0

「マター」の主キーは何ですか?したがって、「訪問」の外来キーは何か、それは「マター」を参照していますか?私は正解にちょうど合うソリューションを投稿できると思うが、デザインに深刻な欠陥があるようだ。 Matterの7行目は、そこの1行目と何も変わりません。誰がそれらをどのように区別すべきですか? –

+0

はい。テーブルにはキーがありません。はい、基本的には同じです。それで私はどのように差別化するのか分かりません。 – william

答えて

1

あなたは、あなたが持っているテーブルでやりたいことはできません。私が正しく理解すれば、訪問の行1が行1と行2にリンクされ、訪問4の行4が行7にリンクされ、noOfContentが3に等しいことを意味します。

唯一のフィールドあなたはテーブル間をリンクする必要がありますtracknoとを使用して3行の訪問の行1と3つの行7のnoOfContentので、3つの行があります。

場合は、フィールドtmstampにリンクすることは可能かもしれませんリンクする必要がある行の訪問とマターで同じです。その場合、あなたの実際のデータをチェックしなければなりません。

この質問に対する正解は、テーブル構造を再設計し、訪問のプライマリキーを特定し、それをMatterの外部キーとして追加する必要があることです。

編集1 Crimsonlandによって与えられる答えが理由trackno列内の1つの値が別のStaffNameによって再利用することができないという仮定の正しい結果を与えます。あなたのデータでは、trackno 1はJohnに属し、trackno 2と3はJamesに属しているようです。そのような場合は、そのクエリはあなたのために動作します。

編集2 ここでは、matterがどの訪問に関連しているか把握するためにtmstampを使用するバージョンがあります。 Matter.tmstampがリンクされた行のVisit.tmstampよりも大きいと仮定し、Visitの1行の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」が挿入されているが、「マター」のための「行1」は、「3.05午後」に挿入されている可能性がある。そして、「マター」のための「行2」は5分後にbとなるかもしれない。 – william

+0

残念ながら、そうではありません。 – william

+0

@william - tmstampを使用して何をすべきかを把握するクエリを公開しました。それはあなたのために働くかもしれません。それはtmstampフィールドの値に依存します。 –

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 

第二問合せ: 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 

、ない完璧なコードのようなもの!しかしそれは不可欠な考えです。

希望すると助かります!

関連する問題