我有三个表来存储客户,顾客访问商店和商店评论:
客户
ID
出生日期...等
CustomerVisits
CUSTOMER_ID
商店编号
VisitDate
评论
商店编号
CUSTOMER_ID
评分
我需要获得的(希望)单个SQL语句是每个商店的所有访问者数量,每个商店过去30天内的访问者数量,每个商店的平均客户年龄以及每个商店的平均评价得分。我需要能够使用IN子句同时为多个商店执行此操作,例如Store_ID IN(1,2,3)。我知道我可以创建一个临时表并循环遍历store_ids,运行多个选择,但如果可能的话,宁愿在单个选择中执行此操作。
提前致谢!
答案 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