【问题标题】:SQL organise a table into summarised viewSQL 将表组织成汇总视图
【发布时间】:2017-03-06 20:34:38
【问题描述】:

我目前有一个类似这样的sql表

 +---------+--------------+------------+
| Company | Contact Type | Start Time |
+---------+--------------+------------+
| x       | Call         | 01/01/2016 |
| x       | Call         | 02/01/2016 |
| x       | Meeting      | 02/01/2016 |
| x       | Email        | 03/01/2016 |
| y       | Meeting      | 01/01/2016 |
| y       | Email        | 01/02/2016 |
| y       | Call         | 02/02/2016 |
| z       | Call         | 09/01/2016 |
| z       | Call         | 24/01/2016 |
| z       | Meeting      | 10/01/2016 |
| z       | Meeting      | 06/01/2016 |
+---------+--------------+------------+

我想要生成一个表格,以下列格式显示最近的联系人类型:

+---------+------------+------------+------------+
| Company |    Call    |  Meeting   |   Email    |
+---------+------------+------------+------------+
| x       | 02/01/2016 | 02/01/2016 | 03/01/2016 |
| y       | 02/02/2016 | 01/01/2016 | 01/02/2016 |
| z       | 24/01/2016 | 10/01/2016 | Null       |
+---------+------------+------------+------------+

现在我可以在 SSRS 中让它看起来像这样,并将数据集转换为交叉表矩阵报告,但我想在 SQL 中生成它。我还设法通过使用大量子查询来实现这一点,但这似乎不是一种有效的方法,而且真正的表有数百万行和比呼叫、会议和电子邮件更多的联系人类型。所以问题是,产生第二个表的最有效方法是什么。为了论证起见,让我们说提取表 1 的 sql 代码是:

SELECT Company, [Contact Type], [Start Time] From Db.dbo.History

【问题讨论】:

  • 仅供参考:所有日期的格式为 dd/mm/yyyy
  • 列开始时间的数据类型?

标签: sql sql-server-2008 tsql


【解决方案1】:

您也可以这样做:(使用 PIVOT)

-- Your Sample
WITH List AS
(
    SELECT 'x' AS Company, 'Call'    AS ContactType, '01/01/2016' AS StartTime UNION ALL
    SELECT 'x' AS Company, 'Call'    AS ContactType, '02/01/2016' AS StartTime UNION ALL
    SELECT 'x' AS Company, 'Meeting' AS ContactType, '02/01/2016' AS StartTime UNION ALL
    SELECT 'x' AS Company, 'Email'   AS ContactType, '03/01/2016' AS StartTime UNION ALL
    SELECT 'y' AS Company, 'Meeting' AS ContactType, '01/01/2016' AS StartTime UNION ALL
    SELECT 'y' AS Company, 'Email'   AS ContactType, '01/02/2016' AS StartTime UNION ALL
    SELECT 'y' AS Company, 'Call'    AS ContactType, '02/02/2016' AS StartTime UNION ALL
    SELECT 'z' AS Company, 'Call'    AS ContactType, '09/01/2016' AS StartTime UNION ALL
    SELECT 'z' AS Company, 'Call'    AS ContactType, '24/01/2016' AS StartTime UNION ALL
    SELECT 'z' AS Company, 'Meeting' AS ContactType, '10/01/2016' AS StartTime UNION ALL
    SELECT 'z' AS Company, 'Meeting' AS ContactType, '06/01/2016' AS StartTime 
)


SELECT Company, Call, Meeting, Email
FROM
(
  SELECT StartTime, ContactType, Company
    FROM List
) L
PIVOT
(
  MAX(StartTime)
  FOR ContactType IN (Call, Meeting, Email)
) CT

My result

【讨论】:

  • 这对我有用。这意味着没有子查询,并且速度有了很大的提高。完美!
【解决方案2】:

做一个GROUP BY。使用case表达式进行条件聚合:

SELECT Company,
       max(case when [Contact Type] = 'Call' then [Start Time] end) [Call],
       max(case when [Contact Type] = 'Meeting' then [Start Time] end) [Meeting],
       max(case when [Contact Type] = 'Email' then [Start Time] end) [Email]
From Db.dbo.History
group by Company

【讨论】:

    【解决方案3】:

    您可以在这里使用 CASE:

    SELECT Company
        ,CASE [Contact Type] WHEN 'Call' THEN  MAX([Start Time]) END AS [Call]
        ,CASE [Contact Type] WHEN 'Meeting' THEN  MAX([Start Time]) END AS  [Meeting]
        ,CASE [Contact Type] WHEN 'Email' THEN  MAX([Start Time]) END AS    [Email]
    From Db.dbo.History
    GROUP BY Company
    

    【讨论】:

    • 我可以知道有人否决这个答案的原因吗?
    猜你喜欢
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    相关资源
    最近更新 更多