我正在使用带有companyID,得分和时间戳的表。
运行SELECT会生成一个客户列表及其随时间变化的分数,这里的示例仅限于一个companyID:
https://i.stack.imgur.com/f09aD.png
我想生成一个列表,其中包含得分在最近的两个时间戳上下降了x%的所有companyID,但我对SQL相对较新,并且不确定如何实现这一点。任何帮助将不胜感激。
答案 0 :(得分:0)
SELECT * FROM (
SELECT companyProfileId, engagementScore, row_number() OVER(PARTITION BY companyProfileId ORDER BY createTimeStamp Desc) AS rowNum
FROM _yourTable_) AS foo
WHERE foo.rowNum() <= 2
AND engagementScore * X = y
over Clause mssql希望您使用的是mssql,因为这不适用于其他rdbms&#39;
答案 1 :(得分:0)
这是在MS SQL和MySQL中测试的替代解决方案。我在http://sqlfiddle.com上测试了这个。
这是查询。它可能不是最有效的,但它相当简单。
SELECT
EN3.companyProfileId
, EN3.maxCreateTimestamp
, EN3.secondMaxCreateTimestamp
, EN4.engagementScore newestEngagementScore
, EN5.engagementScore secondNewestEngagementScore
, EN4.engagementScore - EN5.engagementScore AS engagementDifference
, 100.0 * (EN4.engagementScore - EN5.engagementScore) / EN5.engagementScore percentDifference
FROM
(
SELECT
EN1.companyProfileId
, EN2.maxCreateTimestamp
, MAX(EN1.createTimestamp) secondMaxCreateTimestamp
FROM
engagement EN1
INNER JOIN
(
SELECT
companyProfileId
, MAX(createTimestamp) maxCreateTimestamp
FROM
engagement
GROUP BY
companyProfileId
) EN2
ON
EN1.companyProfileId = EN2.companyProfileId
AND EN1.createTimestamp != EN2.maxCreateTimestamp
GROUP BY
EN1.companyProfileId
, EN2.maxCreateTimestamp
) EN3
INNER JOIN
engagement EN4
ON
EN3.companyProfileId = EN4.companyProfileId
AND EN3.maxCreateTimestamp = EN4.createTimestamp
INNER JOIN
engagement EN5
ON
EN3.companyProfileId = EN5.companyProfileId
AND EN3.secondMaxCreateTimestamp = EN5.createTimestamp
WHERE
100.0 * (EN4.engagementScore - EN5.engagementScore) / (EN5.engagementScore) < -10.00
这是为MS-SQL设置的测试数据。
CREATE TABLE engagement (
companyProfileId INT
, engagementScore INT
, createTimestamp DATETIME
);
GO
-- Increased 5%, declined 1%, declined 11%; should be returned for 10%.
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1000, 7500 * 1.05 * 0.99 * 0.89, DATEADD(dd, -1, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1000, 7500 * 1.05 * 0.99, DATEADD(dd, -2, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1000, 7500 * 1.05, DATEADD(dd, -3, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1000, 7500, DATEADD(dd, -4, GETDATE())
-- Only has one score; should not be returned.
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1001, 8000, DATEADD(dd, -1, GETDATE())
-- Declined 15%, declined 15%, increased 15%; should not be returned.
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1002, 6000 * 0.85 * 0.85 * 1.15, DATEADD(dd, -1, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1002, 6000 * 0.85 * 0.85, DATEADD(dd, -2, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1002, 6000 * 0.85, DATEADD(dd, -3, GETDATE())
-- Increased 5%, declined 1%, declined 11%; should be returned for 10%.
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1003, 5000 * 1.05 * 0.89, DATEADD(dd, -1, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1003, 5000 * 1.05, DATEADD(dd, -2, GETDATE())
-- Declined 9%, declined 9%; should not be returned for 10%.
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1004, 9250 * 0.91 * 0.91, DATEADD(dd, -1, GETDATE())
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1004, 9250 * 0.91, DATEADD(dd, -2, GETDATE())
GO
测试数据的MySQL版本非常相似,所以我省略了大部分内容,但它的形式如下:
INSERT INTO engagement(companyProfileId, engagementScore, createTimestamp)
SELECT 1002, 7500 * 0.85 * 0.85 * 1.15, DATE_ADD(CURDATE(), INTERVAL -1 DAY);
答案 2 :(得分:0)
您可以试试这个,使用窗口功能可以解决您的问题......
select a.name
, COUNT(case when subject = 'maths' then 1 end) as maths
, COUNT(case when subject = 'science' then 1 end) as science
from student a
group by a.name