2

我有一个看起来很像这样的数据集:

TrxDate     DayOfWk TrxHour TrxName Succeeded
Oct 21 2012 Sunday  0       signon  1
Oct 21 2012 Sunday  0       Bal     1
Oct 21 2012 Sunday  0       Bal     1
Oct 21 2012 Sunday  0       hist    1
Oct 21 2012 Sunday  0       Bal     1

实际上,我需要使用 anINNER JOIN来获取 uniqueID 以使结果集看起来像这样,但这是一个细节。我得到的要求是:

  • 根据日期、星期几和一天中的小时进行分组。
  • 输出每个组的成功登录次数。
  • 输出每个组的不成功登录数。
  • 输出每个组的登录总数(成功 + 不成功)。
  • 输出每个组的事务总数(本质上是Count(UniqueId))。

所以输出应该是这样的:

Date        Day of Week Hour    Login Success   Login Failures  Total Logins    Total Transactions
11/15/2012  5           22      12,000          1,000           13,000          25,000 
11/15/2012  5           23      15,223          1,500           16,723          33,000 
11/16/2012  6           0       22,000          3,000           25,000          12,554 
11/16/2012  6           1       18,000          2,000           20,000          15,899 

Date显然,在呈现方式和DayOfWk呈现方式上存在细微的风格差异。它们并不重要。

问题:我没有看到比将所有内容转储INNER JOIN到一个临时表中并运行扩展查询以以结果集所需的各种方式对该临时表进行编目更好的方法。这INNER JOIN涉及到两个具有数十万行的表。这种技术是缓慢的,速度方面的,而臃肿的,记忆方面的。这个解决方案会奏效,但我想对我的工作更自豪一点!有没有人有任何想法来更优雅地完成这一点?

我在下面的答案中大吃一惊。我的查询现在看起来像这样:

SELECT
LEFT(first.EntryDateTime, 11) AS [Date]
,DATENAME(weekday, first.EntryDateTime) AS [Day of Week]
,DATEPART(hh, first.EntryDateTime) AS [Hour]
,SUM(CASE WHEN second.TrxName = 'signon' AND first.Succeeded = 1 THEN 1 ELSE 0 END) AS [Login Success]
,SUM(CASE WHEN second.TrxName = 'signon' AND first.Succeeded = 1 THEN 0 ELSE 1 END) AS [Login Failure]
,SUM(CASE WHEN second.TrxName = 'signon' THEN 1 ELSE 0 END) AS [Total Logins]
,COUNT(first.UniqueId) AS [Total Transactions]

FROM
dbo.TheFirstPlace first (NOLOCK)
INNER JOIN
dbo.TheSecondPlace second (NOLOCK)
ON  first.TrxUniqueId = second.TrxUniqueId
WHERE first.EntryDateTime > DATEADD(day, -7, cast(GETDATE() As Date))
GROUP BY
    LEFT(first.EntryDateTime, 11),
    DATENAME(weekday, first.EntryDateTime),
    DATEPART(hh, first.EntryDateTime)

我的结果集如下所示:

Date        Day of Week Hour    Login Success   Login Failure   Total Logins    Total Transactions
Nov  9 2012 Friday      0       554             26245           595             26799
Nov  9 2012 Friday      1       2113            120569          2509            122682
Nov  9 2012 Friday      2       1675            102058          1743            103733

显然,这里的数学根本不起作用,我对为什么感到很困惑。

4

1 回答 1

4

CASE如果您使用andSUM语句的组合,您可能会对数据进行一次传递。这可能比执行多个COUNT查询更有效......如下所示:

SELECT
    [Date],
    [Day of Week],
    [Hour],
    SUM(CASE WHEN TrxName = 'signon' AND Succeeded = 1 THEN 1 ELSE 0 END) AS [Login Success],
    SUM(CASE WHEN TrxName = 'signon' AND Succeeded = 0 THEN 1 ELSE 0 END) AS [Login Failure],
    SUM(CASE WHEN TrxName = 'signon' 1 ELSE 0 END) AS [Total Logins],
    COUNT(UniqueId) AS [Total Transactions]
FROM
    YourTable
GROUP BY
    [Date],
    [Day of Week],
    [Hour]
于 2012-11-16T20:40:47.543 回答