我有一个包含以下值的表:
客户|周末| trailing_avg
客户定义客户输入,周末是每周值,尾随平均值是利用率指标。
我想过滤结果,只显示最近(即最高周末)trailing_avg值连续升序或降序的客户。
因此,如果客户A的最新尾随平均值为7,6,5,则会显示,但如果客户B的平均值为7,8,6,则他们不会。
答案 0 :(得分:0)
你可以创建一个函数,只是为了评估trailing_avg中的趋势,然后让那个构建然后简单的查询来带你去。
看看下面的代码。 这是我的快乐即兴,但希望能帮到你。
DELIMITER //
DROP FUNCTION IF EXISTS f_trend//
CREATE FUNCTION f_trend (trend VARCHAR(100))
RETURNS TEXT
BEGIN
DECLARE cnt TEXT;
SET @p = trend;
SET @p_1n = 0;
SET @p_2n = 0;
SET @c = 0;
SET @diff = 0;
SET @d = 0;
label1: LOOP
SET @c = @c + 1;
SET @p_1n = SUBSTRING_INDEX(@p,',',1);
SET @p_2n = SUBSTRING_INDEX(
REPLACE(@p,CONCAT(@p_1n,','),''),',',1);
SET @p = REPLACE(@p,CONCAT(SUBSTRING_INDEX(@p,',',1),','),'');
SET @diff = @p_2n - @p_1n;
IF @diff > 0 AND ABS(@d) = (@c-1) THEN SET @d = @d + 1;
ELSEIF @diff < 0 AND ABS(@d) = (@c-1) THEN SET @d = @d - 1;
ELSE SET @d = @d;
END IF;
IF @c >= LENGTH(trend) - LENGTH(REPLACE(trend, ',', '')) THEN
LEAVE label1;
END IF;
ITERATE label1;
END LOOP label1;
IF abs(@d) = @c AND @d > 0 THEN
SET cnt=(SELECT 'ASC');
ELSEIF abs(@d) = @c AND @d < 0 THEN
SET cnt=(SELECT 'DESC');
ELSE SET cnt=(SELECT 'N/A');
END IF;
RETURN cnt;
END //
DELIMITER ;
用于检索所需内容的查询:
SELECT customer
FROM info
WHERE weekending = (SELECT MAX(weekending) FROM info)
AND f_trend(trainling_avg) IN ('ASC','DESC');
这不是最佳选择,但一切都取决于您的需求和规模。
答案 1 :(得分:0)
没有日期范围的查询。
WITH tmpt AS (
select Customer,
weekending,
trailing_avg,
CASE WHEN trailing_avg + 1 = LEAD(trailing_avg, 1) OVER(ORDER BY Customer, weekending,trailing_avg) THEN 1 ELSE 0 END AS flg,
CASE WHEN trailing_avg + 1 = LAG(trailing_avg, 1) OVER(ORDER BY customer,weekending,trailing_avg) THEN 1 ELSE 0 END AS flg1
FROM test
), Customer AS (
SELECT Customer, count(flg) AS flg, count(flg1) AS flg1
FROM tmpt
WHERE flg1 = 0 AND flg = 0 GROUP BY Customer
)
SELECT * FROM test WHERE Customer IN (SELECT Customer FROM Customer WHERE flg + flg1 = 2);
我明白出了什么问题 忘了添加PARTITION BY Customer
// trailing_avg < if step metric random or trailing_avg + 1 if step metric only +/-1
-CASE WHEN trailing_avg + 1 = LEAD(trailing_avg, 1) OVER(ORDER BY Customer, weekending,trailing_avg) THEN 1 ELSE 0 END AS flg,
-CASE WHEN trailing_avg + 1 = LAG(trailing_avg, 1) OVER(ORDER BY customer,weekending,trailing_avg) THEN 1 ELSE 0 END AS flg1
+CASE WHEN trailing_avg < LEAD(trailing_avg, 1) OVER(PARTITION BY Customer ORDER BY weekending,trailing_avg) THEN 1 ELSE 0 END AS flg,
+CASE WHEN trailing_avg < LAG(trailing_avg, 1) OVER(PARTITION BY Customer ORDER BY weekending,trailing_avg) THEN 1 ELSE 0 END AS flg1
改变的例子:
WITH tmpt AS (
select Customer,
weekending,
trailing_avg,
CASE WHEN trailing_avg < LEAD(trailing_avg, 1) OVER(PARTITION BY Customer ORDER BY weekending,trailing_avg) THEN 1 ELSE 0 END AS flg,
CASE WHEN trailing_avg < LAG(trailing_avg, 1) OVER(PARTITION BY Customer ORDER BY weekending,trailing_avg) THEN 1 ELSE 0 END AS flg1
FROM test
), Customer AS (
SELECT Customer, count(flg) AS flg, count(flg1) AS flg1
FROM tmpt
WHERE flg1 = 0 AND flg = 0 GROUP BY Customer
)
SELECT * FROM test WHERE Customer IN (SELECT Customer FROM Customer WHERE flg + flg1 = 2);