我有一个表定义如下:
CREATE TABLE [dbo].[ListingStats](
[ListingStatID] [int] IDENTITY(1,1) NOT NULL,
[StatTypeID] [int] NOT NULL,
[CreatedDate] [date] NOT NULL,
[ListingID] [int] NOT NULL,
CONSTRAINT [PK_ListingStats] PRIMARY KEY CLUSTERED
(
[ListingStatID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我想为今天,过去7天,过去30天和所有时间获得每种类型(listingStatTypeID)的4个总计。
我不确定最有效的查询是什么。现在我有以下内容,我可以为每个TYPE重复,但这将是一个大查询,它将是很多电话。
declare @listingID int
set @listingID = 209722
--today
select count(1) from ListingStats where listingid = @listingid and CreatedDate = getdate()
--last 7 days
select count(1) from ListingStats where listingid = @listingid and CreatedDate > getdate()-7
--last 30 days
select count(1) from ListingStats where listingid = @listingid and CreatedDate > getdate()-30
--all time
select count(1) from ListingStats where listingid = @listingid
我总是通过提供一个listingID来一次调用一个列表。 如果有人能提供方向我会很感激。我应该创建某种视图吗?
预期结果
-Type------Today-----7Days---30Days---Ever
1 44 50 500 5000
2 22 40 90 1000
3 55 55 555 5555
答案 0 :(得分:2)
对于单个列表,您可以使用CASE表达式在单个查询中获取四个值:
SELECT SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today,
SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week,
SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month,
COUNT(*) AS v_alltime
FROM ListingStats
WHERE listingid = @listingid
对于所有商家信息ID,
SELECT ListingID,
SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today,
SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week,
SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month,
COUNT(*) AS v_alltime
FROM ListingStats
GROUP BY ListingID
如果要获取每个StatTypeID的摘要(在一个ListingID中),那么:
SELECT ListingID,
StatTypeID,
SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today,
SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week,
SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month,
COUNT(*) AS v_alltime
FROM ListingStats
GROUP BY ListingID, StatTypeID
如果您希望StatTypeID的摘要跨所有ListingID,则:
SELECT StatTypeID,
SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today,
SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week,
SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month,
COUNT(*) AS v_alltime
FROM ListingStats
GROUP BY StatTypeID
根据已添加的“预期结果”部分判断,此最后一个查询最接近您的需求。从评论来看,如果你想通过StatTypeID获得特定的ListingID的摘要,那么:
SELECT StatTypeID,
SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today,
SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week,
SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month,
COUNT(*) AS v_alltime
FROM ListingStats
WHERE ListingID = @listingid
GROUP BY StatTypeID
如果您的getdate()
函数调用存在问题(正如Gordon Linoff中answer所建议的那样),您还需要修复这些问题。
答案 1 :(得分:1)
您可以使用条件聚合执行此操作。这会将值分为四列:
select sum(case when CreatedDate = cast(getdate() as date) then 1 else 0 end) as today,
sum(case when CreatedDate > cast(getdate() - 7 as date) then 1 else 0 end) as lastweek,
sum(case when CreatedDate > cast(getdate() - 30 as date) then 1 else 0 end) as last30,
count(*) as ever
from ListingStats
where listingid = @listingid;
请注意getdate()
返回datetime
,带有时间组件(尽管名称不同),因此此查询会将值转换为日期(删除时间组件)。
要获取所有列表ID的信息:
select sum(case when CreatedDate = cast(getdate() as date) then 1 else 0 end) as today,
sum(case when CreatedDate > cast(getdate() - 7 as date) then 1 else 0 end) as lastweek,
sum(case when CreatedDate > cast(getdate() - 30 as date) then 1 else 0 end) as last30,
count(*) as ever
from ListingStats
group by listingid;