2011-02-07 1 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) 

Matter

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 

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

Для line 1 из Visit таблицы, noOfContenct должен be2 и line 4 из Visit, noOfContent должен быть 1. Таким образом, в целом 3.

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

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

P.S. утверждение не даст итоговое значение, как результат. Вместо этого он будет давать значения строки за строкой.

+0

Что является основным ключом 'Matter'? Соответственно, каким должен быть внешний ключ «Посещения», который ссылается на «Материя»? Я думаю, что я мог бы разместить решение, которое просто соответствовало бы правильному ответу, но, похоже, в дизайне есть серьезный недостаток. Ваша строка 7 в «Материи» ничем не отличается от строки 1 там. Как их отличить? –

+0

Да. в таблицах нет ключа. Да, в принципе, это одно и то же. Вот почему я понятия не имею, как дифференцироваться. – william

ответ

1

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

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

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

Правильный ответ на этот вопрос состоит в том, что вам необходимо перепроектировать структуру вашей таблицы и определить первичный ключ в приложении «Посещение» и добавить это как внешний ключ в Материи.

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

Редактировать 2 Вот версия, в которой я использую tmstamp, чтобы выяснить, что Материя связана с тем, что Визит. Я предполагаю, что Matter.tmstamp больше, чем Visit.tmstamp для связанных строк, и я предполагаю, что последняя вставленная строка в Материи для одной строки в Виде имеет значение 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', это запись времени, когда строка вставлена. Так. 'Строка 1' для' Посещения' вставлена ​​в '3 вечера', но' Линия 1' для 'Материи' может быть вставлена ​​в' 3.05 вечера'. И 'Line 2' для' Matter' может быть пять минут спустя .. так далее и так далее. – william

+0

К сожалению, это не так. – william

+0

@william - Добавлено запрос, в котором используется tmstamp, чтобы выяснить, что делать. Это может сработать для вас. Это зависит от значений в поле tmstamp. –

1

Попробуйте следующее:

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

первый запрос: ВЫБРАТЬ StaffName, tmstamp, trackno, COUNT (1) noOfQno ОТ посещения 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 

второго запроса: ВЫБРАТЬ trackno, COUNT (1) noOfContent из материи 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

вы можете проверить его снова .. я просто добавляю сумму и группу по вашему запросу. – Crimsonland

+0

@william: It * does * работает над образцовыми таблицами, которые вы нам предоставили. Я только что разместил свое решение только для того, чтобы убедиться, что он полностью идентичен Crimsonland, поэтому мой теперь удален, и этот получает поддержку. –

+0

Yup. Я попробовал алди. Тот же результат. – william

0

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

Вы можете посетить посещение Материи на треке Nº и использовать CASE WHEN ... ELSE .... structure. Что-то вроде этого (это неправильный код 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 

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

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

Смежные вопросы