2015-09-16 4 views
0

[ОБНОВЛЕНО]: Я обновил вопрос с помощью предложения WHERE.Полный Outer Присоединиться к группе

У меня есть следующий скрипт SQL. Результат:

| User |   Name | Time | 
|--------|---------------|--------| 
| 00001 |  Mary Jane |  12 | 
| 00002 | Joana Smith |  7 | 
| 00003 | George Andrz |  2 | 
| 00004 | Julia Roberts |  4 | 

Я ожидал этого:

| User |   Name | Time | 
|--------|---------------|--------| 
| 00001 |  Mary Jane |  12 | 
| 00002 | Joana Smith |  7 | 
| 00003 | George Andrz |  2 | 
| 00004 | Julia Roberts |  4 | 
| 90000 | Anderson Math |  0 | 
| 90001 |  Josh Xin |  0 | 

Разница заключается в: Есть некоторые пользователи в MainUsers таблицы, которые не могли бы сделать табель еще, так что TimeSheet стол пуст для человека. Но я хотел бы показать имя, с Time = 0


SQL Fiddle

сервера Настройка MS SQL 2008 схемы:

CREATE TABLE MainUsers 
(
    id int identity primary key, 
    UserID varchar(5), 
    FullName varchar(500), 
); 

INSERT INTO MainUsers 
(UserID, FullName) 
VALUES 
('00001', 'Mary Jane'), 
('00002', 'Joana Smith'), 
('00003', 'George Andrz'), 
('00004', 'Julia Roberts'), 
('90000', 'Anderson Math'), 
('90001', 'Josh Xin'); 

CREATE TABLE TimeSheet 
(
    id int identity primary key, 
    UserID varchar(5), 
    FullName varchar(500), 
    Minutes int, 
    TimeStamp Datetime, 
); 

INSERT INTO TimeSheet 
(UserID, FullName, Minutes, TimeStamp) 
VALUES 
('00001', 'Mary Jane', 240, '2015-09-16 08:16:00'), 
('00001', 'Mary Jane', 480, '2015-09-16 08:16:00'), 
('00002', 'Joana Smith', 320, '2015-09-16 08:16:00'), 
('00002', 'Joana Smith', 120, '2015-09-16 08:16:00'), 
('00003', 'George Andrz', 120, '2015-09-16 08:16:00'), 
('00004', 'Julia Roberts', 240, '2015-09-16 08:16:00'); 

Запрос 1:

SELECT u.UserID AS [User], u.FullName AS Name, 
     SUM(t.Minutes)/60 AS [Time] 
FROM MainUsers u LEFT JOIN 
    TimeSheet t 
    ON u.UserID = t.UserID 
WHERE 
    month(TimeStamp) = 9 and year(TimeStamp) = 2015 
GROUP BY u.UserID, u.FullName 
ORDER BY u.UserID ASC 

Results:

| User |   Name | Time | 
|-------|---------------|------| 
| 00001 |  Mary Jane | 12 | 
| 00002 | Joana Smith | 7 | 
| 00003 | George Andrz | 2 | 
| 00004 | Julia Roberts | 4 | 

Спасибо.

+0

Почему вы используете полное внешнее соединение вместо левого соединения? – Beth

+0

Потому что левое соединение тоже не работает. Я думаю, что Full Outer должен работать, но это не так. – Khrys

+0

нет, вам нужно оставить внешнее соединение со своей основной таблицей (пользователями) с соответствующей таблицей (расписанием). Чтобы присоединиться к последовательности, которую у вас есть, расписание -> пользователи, вы должны использовать ПРАВИЛЬНОЕ внешнее соединение. – Beth

ответ

3

попробовать это:

SELECT 
    u.UserID AS 'User', 
    u.FullName AS Name, 
    isnull(SUM(Minutes)/60,0) AS [Time] 
FROM 
    MainUsers u left OUTER JOIN 
    TimeSheet t ON 
    u.UserID = t.UserID 
GROUP BY 
    u.UserID, 
    u.FullName 
ORDER BY 
    u.UserID 

SQL Fiddle

, если вы хотите включить условия на вашем расписания таблицы, такие как month(timestamp) = 9 and year(timestamp) = 2015 и вы делаете это в пункте WHERE, он преобразует outer join в inner join, потому что в предложении WHERE требуются поля в таблице временных меток. Для ограничения на месяц и год вашего left outer join эд таблицы, вы поставите условия в предложении вместо WHEREJOIN, как:

SELECT 
    u.UserID AS 'User', 
    u.FullName AS Name, 
    isnull(SUM(Minutes)/60,0) AS [Time] 
FROM 
    MainUsers u left OUTER JOIN 
    TimeSheet t ON 
    u.UserID = t.UserID and 
    month(timestamp) = 9 and year(timestamp) = 2015 
GROUP BY 
    u.UserID, 
    u.FullName 
ORDER BY 
    u.UserID 

sql fiddle

+1

Спасибо за удивительную помощь и за учение. – Khrys

1

Я думаю, что вы хотите left join. Предположительно, все с расписанием являются действительным пользователем. И вы, кажется, хотите сохранить всех пользователей.

В общем, когда вы используете full outer join, вы должны быть очень внимательны к значениям NULL. COALESCE() в конечном итоге используется широко. Таким образом, ваш запрос можно записать в виде:

SELECT u.UserID AS [User], u.FullName AS Name, 
     SUM(t.Minutes)/60 AS [Time] 
FROM MainUsers u LEFT JOIN 
    TimeSheet t 
    ON u.UserID = t.UserID 
GROUP BY u.UserID, u.FullName 
ORDER BY u.UserID ASC; 

отметить также, что запрос гораздо легче следовать, когда ваши псевдонимы таблиц являются сокращениями для имен таблиц. A и B ничего не значат. Но ясно, что t означает TimeSheet.

И, наконец, столбец time, вероятно, является часом как целое число - при условии, что Minutes является целым числом. (И это было бы лучше назвать что-то вроде «часов».) Если вы хотите десятичные часов, а затем разделите на 60,0, а не 60.

+0

Спасибо за ответ. Это помогает мне с некоторыми условиями. Я пытаюсь обновить скрипку, но не работает. У меня есть другой столбец в таблице TimeSheet, это 'TimeStamp', столбец datetime. Когда o ставится, например: Где месяц (временная метка) = 9 и год (отметка времени) = 2015, он не показывает нулевые значения. Можете ли вы помочь в этом случае? Благодарю. – Khrys

+0

@Khrys. , , Поместите условие в предложение 'ON', а не' WHERE'. –

0
  1. Изменение Регистрация с FULL OUTER к RIGHT OUTER
  2. группы должны быть по применяется к идентификатору пользователя и имени таблицы MainUsers, а не по тайм-листам
  3. Выбор списка должен быть соответствующим образом изменен.

SQL Fiddle

Запрос 1:

SELECT 
    B.UserID AS 'User', 
    B.FullName AS Name, 
    SUM(A.Minutes)/60 AS [Time] 
FROM 
    TimeSheet A 
RIGHT OUTER JOIN MainUsers B ON A.UserID = B.UserID 
GROUP BY 
    B.UserID, 
    B.FullName 
ORDER BY 
    B.UserID ASC 

Results:

| User |   Name | Time | 
|-------|---------------|--------| 
| 00001 |  Mary Jane |  12 | 
| 00002 | Joana Smith |  7 | 
| 00003 | George Andrz |  2 | 
| 00004 | Julia Roberts |  4 | 
| 90000 | Anderson Math | (null) | 
| 90001 |  Josh Xin | (null) | 

Я думаю, это то, что вы ищете. Надеюсь, это может вам помочь. :)

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