完全外部加入Group By

时间:2015-09-16 18:02:15

标签: sql sql-server-2008-r2 group-by

[已更新]:我已使用WHERE条款更新了问题。

我有以下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,所以TimeSheet表是空的   为了这个人。但我想显示名称,时间= 0

SQL Fiddle

MS SQL Server 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 |

感谢。

3 个答案:

答案 0 :(得分:4)

试试这个:

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 ed表的月份和年份进行限制,请将条件放在JOIN子句而不是WHERE中,例如:

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 :(得分: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;

另请注意,当表别名是表名的缩写时,查询更容易理解。 AB并不意味着什么。但很明显,t代表TimeSheet

最后,time列可能是小时作为整数 - 假设Minutes是一个整数。 (并且最好称之为“小时”。)如果你想要十进制小时数,则除以60.0而不是60。

答案 2 :(得分:0)

  1. 将FULL OUTER更改为RIGHT OUTER
  2. Group by应该应用于MainUsers表的userid和名称,而不是TimeSheets
  3. 应相应修改选择列表。
  4. 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) |
    

    我想,这就是你要找的东西。 希望它可以帮到你。 :)