当 LIMIT 值来自 Mysql 中的子查询时,如何仅查看 table 的一部分
How to view only a portion of the table when the LIMIT value is derived from a subquery in Mysql
对于table'Issue'
-
Call_ref 是唯一标识每个调用的唯一键。每次调用均由用户发出,用户通过 caller_id 标识。每个用户可以拨打多个电话,但每个电话只有一个 caller_id。我想显示前 20% 的活跃用户拨打的电话。
我试过这个查询-
SELECT Caller_id, COUNT(Call_ref) FROM Issue
GROUP BY Caller_id
ORDER BY COUNT(Call_ref)
LIMIT round(COUNT(distinct Caller_id)/5)
但是,LIMIT 似乎只接受数字。有没有一种方法可以将此视图限制为结果 table?
中所有记录的前 20%
如果您使用的是 运行 MySQL 8.0,则可以使用 window 函数执行此操作。根据您当前的查询,那将是:
select *
from (
select caller_id, count(*) , percent_rank() over(order by count(*) desc) prn
from issue
group by caller_id
) t
where prn < 0.2
可以使用动态sql
SELECT CONCAT('SELECT Caller_id, COUNT(Call_ref) FROM Issue
GROUP BY Caller_id
ORDER BY COUNT(Call_ref)
LIMIT ',round(COUNT(distinct Caller_id)/5)) into @sql FROM Caller_id;
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
试试这个代码
SET @row_number = 0;
SET @rows = (select count(distinct Caller_id) from Issue)/5;
select Caller_id, _counter from ( SELECT (@row_number:=@row_number + 1) AS num , Caller_id, COUNT(_counter) cnt FROM Issue
GROUP BY Caller_id FROM Issue ) x where num < @rows
order by _counter
用window函数可以做到,但是GMB的解是错误的(证明:db<>fiddle link)。很遗憾,我不能发表评论。
这是我的解决方案:
CREATE TABLE ranked (
SELECT
a.caller_id
,a.count_calls
,RANK() OVER w AS 'ranked'
,ROW_NUMBER() OVER w AS 'row_num'
FROM
(
SELECT
caller_id
,COUNT(*) count_calls
FROM
issue
GROUP BY 1
ORDER BY 2 DESC
) a
WINDOW w AS (ORDER BY count_calls DESC)
);
CREATE TABLE max_row_num (
SELECT MAX(row_num) AS max_row_num FROM ranked
);
CREATE TABLE result (
SELECT
c.*
FROM
issue c
INNER JOIN
(
SELECT
a.Caller_Id
,a.count_calls
FROM
ranked a
INNER JOIN (SELECT (max_row_num * 20 /100)per FROM max_row_num) b
WHERE
a.ranked <= b.per
) d ON (c.Caller_id = d.Caller_id)
)
SELECT * FROM result;
解决方案:db<>fiddle link
具有 ROW_NUMBER()
和 COUNT(*)
window 函数:
SELECT Caller_id, Counter
FROM (
SELECT Caller_id, COUNT(*) Counter,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) rn,
COUNT(*) OVER () total
FROM Issue
GROUP BY Caller_id
) t
WHERE rn / total <= 0.2
ORDER BY rn
对于table'Issue'
-
Call_ref 是唯一标识每个调用的唯一键。每次调用均由用户发出,用户通过 caller_id 标识。每个用户可以拨打多个电话,但每个电话只有一个 caller_id。我想显示前 20% 的活跃用户拨打的电话。 我试过这个查询-
SELECT Caller_id, COUNT(Call_ref) FROM Issue
GROUP BY Caller_id
ORDER BY COUNT(Call_ref)
LIMIT round(COUNT(distinct Caller_id)/5)
但是,LIMIT 似乎只接受数字。有没有一种方法可以将此视图限制为结果 table?
中所有记录的前 20%如果您使用的是 运行 MySQL 8.0,则可以使用 window 函数执行此操作。根据您当前的查询,那将是:
select *
from (
select caller_id, count(*) , percent_rank() over(order by count(*) desc) prn
from issue
group by caller_id
) t
where prn < 0.2
可以使用动态sql
SELECT CONCAT('SELECT Caller_id, COUNT(Call_ref) FROM Issue
GROUP BY Caller_id
ORDER BY COUNT(Call_ref)
LIMIT ',round(COUNT(distinct Caller_id)/5)) into @sql FROM Caller_id;
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
试试这个代码
SET @row_number = 0;
SET @rows = (select count(distinct Caller_id) from Issue)/5;
select Caller_id, _counter from ( SELECT (@row_number:=@row_number + 1) AS num , Caller_id, COUNT(_counter) cnt FROM Issue
GROUP BY Caller_id FROM Issue ) x where num < @rows
order by _counter
用window函数可以做到,但是GMB的解是错误的(证明:db<>fiddle link)。很遗憾,我不能发表评论。
这是我的解决方案:
CREATE TABLE ranked (
SELECT
a.caller_id
,a.count_calls
,RANK() OVER w AS 'ranked'
,ROW_NUMBER() OVER w AS 'row_num'
FROM
(
SELECT
caller_id
,COUNT(*) count_calls
FROM
issue
GROUP BY 1
ORDER BY 2 DESC
) a
WINDOW w AS (ORDER BY count_calls DESC)
);
CREATE TABLE max_row_num (
SELECT MAX(row_num) AS max_row_num FROM ranked
);
CREATE TABLE result (
SELECT
c.*
FROM
issue c
INNER JOIN
(
SELECT
a.Caller_Id
,a.count_calls
FROM
ranked a
INNER JOIN (SELECT (max_row_num * 20 /100)per FROM max_row_num) b
WHERE
a.ranked <= b.per
) d ON (c.Caller_id = d.Caller_id)
)
SELECT * FROM result;
解决方案:db<>fiddle link
具有 ROW_NUMBER()
和 COUNT(*)
window 函数:
SELECT Caller_id, Counter
FROM (
SELECT Caller_id, COUNT(*) Counter,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) rn,
COUNT(*) OVER () total
FROM Issue
GROUP BY Caller_id
) t
WHERE rn / total <= 0.2
ORDER BY rn