我的代码是这样的:关于避免这么多或陈述的任何想法? (sql server)
SELECT ID, COUNT(*) AS UNIQUE_USERS
FROM
(SELECT Address, ID
FROM Table
WHERE
(DateSent between '2012-12-21 00:00:00' and '2012-12-21 23:59:59' or
DateSent between '2012-12-27 00:00:00' and '2012-12-27 23:59:59' or
DateSent between '2013-01-03 00:00:00' and '2013-01-03 23:59:59' or
DateSent between '2013-02-27 00:00:00' and '2013-02-27 23:59:59' or
DateSent between '2013-03-01 00:00:00' and '2013-03-01 23:59:59' or
DateSent between '2013-03-07 00:00:00' and '2013-03-08 23:59:59' or
DateSent between '2013-03-22 00:00:00' and '2013-03-22 23:59:59'
)AND
GROUP BY Address, ID
) AS USERS
GROUP BY USERS.ID
提前致谢
nionios
答案 0 :(得分:2)
您可以通过投射到某个日期并使用in
:
SELECT ID, COUNT(distinct address)
FROM Table
WHERE cast(datesent as date) in ('2012-12-21', '2012-12-27', '2013-01-03',
'2013-02-27', '2013-03-01', '2013-03-07',
'2013-03-22'
) and . . .
GROUP BY ID
我还修改了查询以使用count(distinct)
而不是子查询。假设address
永远不是NULL
,结果应该相同。如果它可以是NULL
并且你想要计算,那么你可以这样做:
SELECT ID, COUNT(distinct address) +
max(case when address is null then 1 else 0 end)
答案 1 :(得分:0)
DATEPART
函数为您提供一个整数,表示列的日期部分,而不包含时间部分。也许你可以比较一下。
http://msdn.microsoft.com/en-us/library/ms186724.aspx#GetDateandTimeParts
答案 2 :(得分:0)
如果您运行的是SQL Server 2008或更新版本,其中存在数据类型DATE
,您可以更改为:
WHERE CAST(DateSent AS DATE) IN ('2012-12-21','2012-12-27','2013-01-03','2013-02-27','2013-03-07','2013-03-22)
如果在SQL Server 2005上(事实证明),您可以通过以下方式实现相同的目标:
WHERE DATEADD(dd, 0, DATEDIFF(dd, 0, DateSent)) IN
('2012-12-21','2012-12-27','2013-01-03','2013-02-27','2013-03-07','2013-03-22)
答案 3 :(得分:0)
规范SQL解决方案是使用包含要测试的日期的表,并在表和日期表之间执行内部联接,并仅返回在日期表中具有匹配项的源行。
您可以通过多种方式创建日期表:
如果你的日期很少,并且编码也更简单,那么戈登的解决方案会更好。
修改强> 由于日期来自文本文件,您应该使用SSIS或BULK INSERT T-SQL命令在表中导入文件并加入表。
BULK INSERT是首选,因为您可以在同一批次中同时组合BULK INSERT和查询语句。 BULK INSERT要求文件是一个简单的分隔文件,文本数据可以转换为目标列的类型,而无需显式转换。 BULK INSERT可以处理一些转换,但对于简单的工作来说可能会变得太麻烦。
SSIS在导入数据时具有很大的灵活性,但它可以使用YetAnotherExternalTool。
答案 4 :(得分:0)
SQL2005或之后
WITH Dates AS
(
SELECT '2012-12-21' AS DateToCheck
UNION SELECT '2012-12-27'
UNION SELECT '2013-01-03'
UNION SELECT '2013-02-27'
UNION SELECT '2013-03-01'
UNION SELECT '2013-03-07'
UNION SELECT '2013-03-22'
)
SELECT ID, COUNT(*) AS UNIQUE_USERS
FROM dbo.Table
INNER JOIN Dates ON CONVERT(Date, DateSent) = DateToCheck
GROUP BY ID
答案 5 :(得分:0)
如果您将时间戳转换为日期,并且由于您的范围是整天,从逻辑上讲,您可以将其编码为单个IN (...)
:
...
SELECT Address, ID
FROM Table
WHERE CAST (DateSent AS DATE) IN ('2012-12-21', '2012-12-27', '2013-01-03', '2013-02-27', '2013-03-01', '2013-03-07', '2013-03-22')
...
答案 6 :(得分:0)
如果你有大表,你可以创建一个带有ID和日期的索引视图。
CREATE VIEW VIEW_TABLE WITH SCHEMABINDING
AS
SELECT ID, CONVERT(DATE, DATESENT) DateSent
FROM TABLE
GO
CREATE NONCLUSTERED INDEX ixDateView
ON [VIEW_Table] (DateSent)
在
SELECT ID, COUNT(distinct address)
FROM View_Table WITH (NOEXPAND)
WHERE DateSent in (
'2012-12-21',
'2012-12-27',
'2013-01-03',
...)
GROUP BY ID
答案 7 :(得分:0)
create table #dates (DateFrom datetime, DateTo datetime)
insert into #dates (DateFrom, DateTo) values
('2012-12-21 00:00:00', '2012-12-21 23:59:59')
, ('2012-12-27 00:00:00', '2012-12-27 23:59:59')
etc...
SELECT ID, COUNT(*) AS UNIQUE_USERS
FROM
(SELECT DISTINCT Address, ID
FROM [Table]
join #dates on [Table].DateSent between #dates.DateFrom and #dates.DateTo
) AS USERS
GROUP BY USERS.ID