这是适当使用temptables吗?

时间:2012-11-16 20:25:01

标签: sql sql-server-2008 tsql

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

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

实际上,我需要使用INNER 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 

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

问题:我没有看到更好的方法来执行此操作,而不是将INNER JOIN中的所有内容转储到temptable中,并将扩展查询运行到以各种方式临时表达的目录中结果集要求。 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

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

1 个答案:

答案 0 :(得分:4)

如果您使用CASESUM语句的组合,则可以对数据进行一次传递。执行多个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]