SQL - 使用条件获取多个计数

时间:2013-03-06 13:40:07

标签: sql sql-server

我有三个表来存储客户,顾客访问商店和商店评论:

客户
ID
出生日期...等

CustomerVisits
CUSTOMER_ID
商店编号
VisitDate

评论
商店编号
CUSTOMER_ID
评分

我需要获得的(希望)单个SQL语句是每个商店的所有访问者数量,每个商店过去30天内的访问者数量,每个商店的平均客户年龄以及每个商店的平均评价得分。我需要能够使用IN子句同时为多个商店执行此操作,例如Store_ID IN(1,2,3)。我知道我可以创建一个临时表并循环遍历store_ids,运行多个选择,但如果可能的话,宁愿在单个选择中执行此操作。

提前致谢!

2 个答案:

答案 0 :(得分:2)

您可以按如下方式在子查询中执行每个计数:

SELECT  Stores.Store_ID,
        review.AvgRating,
        cv.VisitsLast20days,
        cv.TotalVisits,
        cv.AvgCustomerAge
FROM    Stores
        LEFT JOIN
        (   SELECT  Store_ID, [AvgRating] = AVG(Rating)
            FROM    Reviews
            GROUP BY Store_ID
        ) review
            ON review.Store_ID = Stores.Store_ID
        LEFT JOIN
        (   SELECT  CustomerVisits.Store_ID,
                    [VisitsLast30Days] = COUNT(CASE WHEN CustomerVisits.VisitDate >= DATEADD(DAY, -30, CURRENT_TIMESTAMP) THEN 1 END),
                    [TotalVisits] = COUNT(*),
                    [AvgCustomerAge] = AVG(DATEDIFF(DAY, Customer.BirthDate, CURRENT_TIMESTAMP)) / 365.25
            FROM    CustomerVisits
                    INNER JOIN Customer
                        ON Customer.Customer_ID = CustomerVisits.Customer_ID
            GROUP BY CustomerVisits.Store_ID
        ) cv
            ON cv.Store_ID = Stores.Store_ID;

我假设您有一个名为stores的表来执行此操作,并假设不是每个商店都有访问或审核时使用LEFT JOIN。

我还使用了一种相当粗略的方法来计算顾客的平均年龄,但鉴于它只是一个平均值,并且实际上并没有确定一个人的准确年龄,我怀疑它会对结果产生不利影响< / p>

答案 1 :(得分:1)

尝试:

select s.Store_ID,
       count(distinct v.Customer_ID) all_time_visitors,
       count(distinct case when datediff(d, v.VisitDate, getdate()) <= 30 then v.Customer_ID end) 30day_visitors,
       avg(datediff(yy, c.BirthDate, getdate())) avg_customer_age,
       max(r.avg_rating) avg_rating
from Stores s
left join CustomerVisits v on s.Store_ID = v.Store_ID
left join Customers c on v.Customer_ID = c.Customer_ID
left join (select Store_ID, avg(Rating) avg_rating
           from Reviews
           group by Store_ID) r on s.Store_ID = r.Store_ID
where s.Store_ID in (1,2,3) /*amend as required*/
group by s.Store_ID