Как связать следующие 2 таблицы, чтобы получить результат, который показан ниже в SQL Server? (Продолжение) - PullRequest
0 голосов
/ 07 февраля 2011

Визит

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

Я уже задавал этот вопрос.(аналогично этому вопросу.)

как связать следующие 2 таблицы, чтобы получить результат, показанный ниже в 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

Это потому, что

Для line 1 таблицы Visit, noOfContenct должно быть 2, а для line 4 из Visit, noOfContent должно быть 1. Итак, всего 3.

Но согласно этому ответу: для line 1, noOfContent равно 3, для line 4 также 3. Тогда общее значение становится равным 6.

Поэтому я спрашиваю, как обновитьэто утверждение.

PS утверждение не даст итоговую сумму, как результат.Вместо этого он будет давать построчное значение.

Ответы [ 3 ]

1 голос
/ 07 февраля 2011

Вы не можете делать то, что вы хотите с таблицами, которые у вас есть. Если я вас правильно понимаю, вы имеете в виду, что строка 1 в Визите связана со строкой 1 и 2 в Материи, а строка 4 в Визите связана со строкой 7 в Материи, и это даст noOfContent равный 3.

Единственное поле, которое вы должны связать между таблицами - это trackno, и при этом у вас будет три строки из Matter для строки 1 в Visit и три строки для строки 7, поэтому noOfContent равен 6.

Может быть возможно связать поле tmstamp, если оно совпадает в столбцах Визит и Материя для строк, которые должны быть связаны. Вы должны проверить свои фактические данные, чтобы узнать, так ли это.

Правильный ответ на этот вопрос заключается в том, что вам необходимо изменить структуру таблицы, определить первичный ключ в Visit и добавить его в качестве внешнего ключа в Matter.

Редактировать 1 Ответ, данный Crimsonland, дает правильный результат из-за предположения, что одно значение в столбце trackno не может быть повторно использовано другим StaffName. Похоже, что по вашим данным трекно 1 принадлежит Джону, а трекно 2 и 3 принадлежит Джеймсу. Если это так, то этот запрос будет работать для вас.

Редактировать 2 Вот версия, где я использую tmstamp, чтобы выяснить, какое значение имеет Matter к тому, что Visit. Я предполагаю, что Matter.tmstamp больше, чем Visit.tmstamp для связанных строк, и я предполагаю, что последняя вставленная строка в Matter для одной строки в посещении имеет значение 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
1 голос
/ 07 февраля 2011

Попробуйте:

Я создаю пример таблицы с точными данными из вашего примера.Исходя из этого, я протестировал ваш запрос и получил следующее.

1-й запрос: SELECT StaffName, tmstamp, trackno, COUNT (1) noOfQno FROM Посетите GROUP BY StaffName, tmstamp, trackno

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

2-й запрос: ВЫБРАТЬ trackno, COUNT (1) noOfContent FROM Matter GROUP BY trackno

trackno noOfContent
1   3
2   3
3   3

Регистрация:

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 голосов
/ 07 февраля 2011

Я не совсем уверен насчет присоединения к отметке времени.

Вы можете оставить посещение Matter на треке Nº и использовать структуру 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

Опять не идеальный код! Но это основная идея.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...