sql - 用于 Microsoft Access 2013 的 SQL
问题描述
我正在尝试计算返回以获得额外服务的客户的数量,该数量考虑了服务之前的评估分数比较,按服务类型分组。(最终,我还希望能够忽略原始服务一个月内的退货,但我很确定我可以自己解决这个问题)
在计算特定服务的结果时,它应该查看任何服务类型的回报,而不仅仅是原始服务类型。(编辑:*它还应该查看所有未来的回报,而不仅仅是下一个或最近的*)。
它不需要经常运行,但是有 15000+ 行数据,并且计算资源受到动力不足的机器的限制(这是针对非营利组织的),因此效率会很好,但不是绝对需要的。
样本数据
ServiceTable
CustomerID Service Date ScoreBefore
A Service1 1/1/2017 1
A Service2 1/3/2017 1
A Service1 1/1/2018 4
B Service3 3/1/2018 3
B Service1 6/1/2018 1
B Service1 6/2/2018 1
C Service2 1/1/2019 4
C Service2 6/1/2019 1
结果应该是(不考虑日期填充选项):
Service1
ReturnedWorse 0
ReturnedSame 2
ReturnedBetter 1
Service2
ReturnedWorse 1
ReturnedSame 0
ReturnedBetter 1
Service3
ReturnedWorse 2
到目前为止,我已经尝试创建生成表查询,然后可以查询这些查询以获取聚合信息,但我有点卡住并怀疑可能有更好的路线。
我试过的:
SELECT CustomerID, Service, Date, ScoreBefore INTO ReturnedWorse
FROM ServiceTable AS FirstStay
WHERE ((((SELECT COUNT(*)
FROM ServiceTable AS SecondStay
WHERE FirstStay.CustomerID=SecondStay.CustomerID
AND
FirstStay.ScoreBefore> SecondStay.ScoreBefore
AND
SecondStay.Date > FirstStay.Date))));
任何帮助将不胜感激。
解决方案
使用窗口函数会更容易做到这一点,但它们在 ms-access 中不可用。
这是一个查询,可以解决我对您的问题的理解:
t0
:在表中选择一条记录(购买服务的客户)t1
: 拉出同一客户下一次与INNER JOIN
相关子查询签订任何服务时对应的记录(如果没有该记录,则不考虑初始记录)- 将上一条记录的得分与当前记录进行比较
- 按服务 ID 对结果进行分组
您可以在这个 db fiddlde中看到它的实际效果。结果与您的预期略有不同(请参阅我的评论)......但它们与上述解释一致;您可能希望使用相同的原则调整某些规则以匹配您的确切预期结果。
SELECT
t0.service,
SUM(CASE WHEN t1.scorebefore < t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedWorse,
SUM(CASE WHEN t1.scorebefore = t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedSame,
SUM(CASE WHEN t1.scorebefore > t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedBetter
FROM
mytable t0
INNER JOIN mytable t1
ON t0.customerid = t1.customerid
AND t0.date < t1.date
AND NOT EXISTS (
SELECT 1
from mytable
WHERE
customerid = t1.customerid
AND date < t1.date
AND date > t0.date
)
GROUP BY t0.service
| 服务 | 返回更糟 | 返回相同 | 返回更好 | | -------- | ------------- | ------------ | -------------- | | 服务1 | 0 | 2 | 0 | | 服务2 | 1 | 0 | 1 | | 服务3 | 1 | 0 | 0 |
从您的评论中,我了解到您想要考虑所有未来的回报,而不仅仅是下一个回报。这消除了对相关子查询的需要,并且实际上产生了您的预期输出。看到这个数据库小提琴:
SELECT
t0.service,
SUM(CASE WHEN t1.scorebefore < t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedWorse,
SUM(CASE WHEN t1.scorebefore = t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedSame,
SUM(CASE WHEN t1.scorebefore > t0.scorebefore THEN 1 ELSE 0 END) AS ReturnedBetter
FROM
mytable t0
INNER JOIN mytable t1
ON t0.customerid = t1.customerid
-- AND t0.service = t1.service
AND t0.date < t1.date
GROUP BY t0.service
| 服务 | 返回更糟 | 返回相同 | 返回更好 | | -------- | ------------- | ------------ | -------------- | | 服务1 | 0 | 2 | 1 | | 服务2 | 1 | 0 | 1 | | 服务3 | 2 | 0 | 0 |
推荐阅读
- elasticsearch - ElasticSearch Indicies 的数量是否有限制?
- python - 如何推断 Python 构造中数据结构字段的值?
- javascript - 类型 'A | 上不存在属性 'prop' 乙'
- c++ - 本地主机的 IWebViewControl
- maven - 无法在项目自动化上执行目标 org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M3:test (default-test):有测试失败
- caching - 无法从用户缓存 Google Apps 脚本中检索对象
- .net - 使用 WinSCP .NET 找不到方法异常 (EventWaitHandle..ctor)
- javascript - 将模块的多个命名导出导入单个对象
- javascript - jQuery按钮一键两用功能
- java - 在另一幅图像中查找点的模式(OpenCV)