正在从具有或多或少具有这种布局的表中寻找真正的快速而肮脏的数据转储...
ID | EventType | EventDate
------+-------------+------------
1 | Inbound | 2018-07-18 00:00:00
2 | Outbound | 2018-07-18 12:00:00
3 | Inbound | 2018-07-19 00:12:00
4 | Failure | 2018-07-19 00:12:00
5 | Inbound | 2018-07-19 00:12:00
6 | Outbound | 2018-07-19 00:12:00
| |
我想要的是一个查询,它每天查询一次每次出现的次数。所以“ 2018-07-19”会让我吐痰
Failures | Inbounds | Outbounds
-----------+----------+------------
1 | 2 | 1
这是我真正的尝试,但我认为有一种更轻松的方法来摆脱它。理想情况下,我可以将其拖放到视图中并按日期自行过滤,但是如果我需要在存储过程中传递目标日期,那很好。
我的数据库中只有3种已定义的事件类型,因此我对每一种进行计数的静态解决方案就可以了。动态地适应各种不同事件类型的方法会更好,但不是必须的
DECLARE @TestDate datetime2 = '2018-07-19 08:41:55'
SELECT
'Failures' = SUM(Failures),
'Inbounds' = SUM(Inbounds),
'Outbounds'= SUM(Outbounds)
FROM (
SELECT 'Failures' = COUNT(ID), 'Inbounds' = 0, 'Outbounds' = 0 FROM tblTests WHERE EventType = 'Failed' AND EventDate BETWEEN CAST(@TestDate AS DATE) AND DATEADD(DAY, 1, CAST(@TestDate AS DATE)) UNION
SELECT 'Failures' = 0, 'Inbounds' = COUNT(ID), 'Outbounds' = 0 FROM tblTests WHERE EventType = 'Inbound' AND EventDate BETWEEN CAST(@TestDate AS DATE) AND DATEADD(DAY, 1, CAST(@TestDate AS DATE)) UNION
SELECT 'Failures' = 0, 'Inbounds' = 0, 'Outbounds' = COUNT(ID) FROM tblTests WHERE EventType = 'Outbound' AND EventDate BETWEEN CAST(@TestDate AS DATE) AND DATEADD(DAY, 1, CAST(@TestDate AS DATE))
) FIO
答案 0 :(得分:1)
执行此类操作的简单方法称为条件聚合:
https://github.com/redtempo/dnnstuff.aggregator
答案 1 :(得分:1)
在我看来,这将是一个使用计数总计的枢轴的绝佳机会。 下面的示例逐步创建了一个测试表,将OP原始问题中的数据加载到该表中,并将结果按日期排列
创建测试表
create table testtable (id int, value varchar(20), dt datetime)
将临时数据加载到新表中
insert into testtable
values( 1, 'Inbound', '2018-07-18 00:00:00'),
(2, 'Outbound', '2018-07-18 12:00:00'),
(3, 'Inbound' , '2018-07-19 00:12:00'),
(4, 'Failure' , '2018-07-19 00:12:00'),
(5, 'Inbound' , '2018-07-19 00:12:00'),
(6, 'Outbound' , '2018-07-19 00:12:00')
将数据透视正确的结果
select * from (
select value, cast(dt as date) d
from testtable )a
pivot(
count(value) for value in ([Inbound],[Outbound],[Failure]))piv
这将返回结果作为结果
可以通过在枢轴中添加其他值来轻松扩展此范围。
答案 2 :(得分:0)
这就是您需要的
SELECT EventType, COUNT(1) AS Cnt, CONVERT(DATE, EventDate) AS EventDate
FROM dbo.tblTests
GROUP BY EventType, CONVERT(DATE, EventDate)
您可以输入WHERE
以将结果限制为特定日期。
如果您打算经常运行它并在大表上运行它,建议您创建一个仅包含日期的计算的持久性列,
您可以这样做:
ALTER TABLE tblTests ADD DateOnly AS CONVERT(DATE, EventDate) PERSISTED NOT NULL
然后在上述查询中使用DateOnly
代替CONVERT(DATE, EventDate)
。
为了获得最佳性能,您可以在EventType
和新的DateOnly
列上创建索引
像这样:
CREATE NONCLUSTERED INDEX [NCI_tblTest__EventType__DateOnly] ON [dbo].[tblTests]
(
[EventType] ASC,
[DateOnly ] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
并记住要定期重建索引。
编辑: 这将在单独的行上为您提供不同的事件类型。
EDIT2:使用PIVOT
以与所需完全相同的方式产生结果。留给您锻炼:) https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017