【问题标题】:SQL - Getting multiple counts with criteriaSQL - 使用标准获取多个计数
【发布时间】:2013-03-06 13:40:06
【问题描述】:

我有三个表,分别存储客户、客户到店次数和商店评论:

客户
身份证
生日...等等。

客户访问次数
客户 ID
Store_ID
访问日期

评论
Store_ID
客户 ID
评分

我需要在一条 SQL 语句中获取(希望如此)是每家商店的所有时间访客计数、每家商店过去 30 天内的访客人数、每家商店的平均顾客年龄和每家商店的平均评论分数.我需要能够使用像 where Store_ID IN (1,2,3) 这样的 IN 子句同时为多个商店执行此操作。我知道我可以创建一个临时表并循环通过 store_ids,运行多个选择,但如果可能的话,我宁愿在单个选择中执行此操作。

提前致谢!

【问题讨论】:

标签: sql sql-server


【解决方案1】:

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

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。

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

【讨论】:

    【解决方案2】:

    试试:

    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
    

    【讨论】:

    • 'Y' 是 DAYOFYEAR 的简写,而不是 YEAR,因此此处的 avg_customer_age 以天为单位。
    • @GarethD:天哪!谢谢 - 我已经相应地修改了查询。
    猜你喜欢
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多