MySQL根据之前的查询结果将两个查询交织在一起
我有一个表:id、client、domain和bytes。我有一个查询,可以按客户端获取前3名用户:MySQL根据之前的查询结果将两个查询交织在一起,mysql,sql,Mysql,Sql,我有一个表:id、client、domain和bytes。我有一个查询,可以按客户端获取前3名用户: SELECT client FROM log GROUP BY 1 ORDER BY SUM(bytes) DESC LIMIT 3 或按域 SELECT domain FROM log GROUP BY 1 ORDER BY SUM(bytes) DESC LIMIT 3 在MySQL中,有没有一种方法可以在不使用存储过程的情况下将这两者混合在一起?例如,获取前3个客户端,每个客户端行后跟
SELECT client FROM log
GROUP BY 1
ORDER BY SUM(bytes) DESC
LIMIT 3
或按域
SELECT domain FROM log
GROUP BY 1
ORDER BY SUM(bytes) DESC
LIMIT 3
在MySQL中,有没有一种方法可以在不使用存储过程的情况下将这两者混合在一起?例如,获取前3个客户端,每个客户端行后跟该客户端在单个查询执行中使用的前3个域
- 192.168.1.1
- 谷歌网站
- facebook.com
- twitter.com
- 192.168.1.2
- facebook.com
- twitter.com
SELECT domain FROM log
WHERE client = '192.168.1.1'
GROUP BY 1
ORDER BY SUM(bytes) DESC
LIMIT 3
因此,对于查询#1中的每一行,应该以某种方式执行该查询。到目前为止,我已经为每个客户端显示了一个顶级域的串联列表,遗憾的是与同一个客户端无关,因为我无法在子查询中访问outer\u client
:
SELECT client AS outer_client, top_domain
FROM log
JOIN (
SELECT GROUP_CONCAT(t.domain) AS top_domain
FROM (
SELECT domain
FROM log
WHERE client = outer_client
GROUP BY 1
ORDER BY SUM(bytes)
LIMIT 5
) t
) k
GROUP BY client
ORDER BY SUM(bytes)
LIMIT 5;
假设您有权访问PHPMySQL,并且您的服务器允许访问,那么您需要的是一个视图 编写SQL以获取数据集。您可以将其保存在视图中,而不是将其保存在临时表中(这将使其成为静态的)。一旦拥有了该视图,您就可以像使用表一样使用它。事实上,它实际上以表格格式显示数据集,就好像数据集就是这样。
您可以使用连接对其运行查询。。。你想用桌子做什么都行。
这是实际的实时数据。根据您的问题,在每个示例中,您是按相同的内容进行排序的。如果是这种情况,那么返回的行中应该已经包含客户端和域。这能解决你的问题吗
SELECT client, domain FROM log
GROUP BY 1
ORDER BY SUM(bytes) DESC
LIMIT 3
一个解决方案:
我的输出:
+-------------+--------------+--------------+-------------+
| client | domain1 | domain2 | domain3 |
+-------------+--------------+--------------+-------------+
| 192.168.1.1 | google.com | facebook.com | twitter.com |
| 192.168.1.2 | facebook.com | twitter.com | NULL |
+-------------+--------------+--------------+-------------+
这是:
select client,
substring_index(group_concat(domain order by sumbytes desc), ',', 5) as top5domains
from (
select client, domain, sum(bytes) as sumbytes
from log
group by client, domain
) cd
group by client
order by sum(sumbytes) desc
limit 5;
由@Gordon Linoff在此提供:是的,日志中的每一行都是从客户端到域的一次命中,该域获得了一定数量的字节,因此字节列可以供客户端或域使用。如果可以在命令中完成,这会很酷,是吗?为什么这会被否决,因为它是100%正确的?!无论如何你说的“命令”是什么意思?一个单一的查询执行,不是视图,不是存储过程,不是php或其他语言干预。根据我读到的,他指定“没有存储过程”。我看不到任何观点,投票吧。如果它是我的一个用户,我可能会推荐一个视图。不,这将使我每个客户端有一个域(甚至不是该客户端使用最多的域),我需要顶级客户端#1,然后是该客户端使用的3个顶级域。是的,就是这样!有没有办法获得任意数量的域?例如10而不重复?有没有办法优化这个查询?@einundswanzig是的,有办法。使用临时表。正在研究一种拥有任意数量域的方法,不久将拥有它。。。敬请期待。它将全部放在一个语句中——没有存储的进程,没有视图,没有临时表。也许改天吧。我知道这是可能的,但要得到一般情况却相当困难。我想用GROUP_CONCAT来创建一个逗号分隔的域列表,这样它就可以扩展了。但是由于缺少诸如
RANK
之类的窗口函数,这就不容易了,而且很难通过双嵌套子查询传递变量。无论如何,谢谢你的投票和勾选。
select client,
substring_index(group_concat(domain order by sumbytes desc), ',', 5) as top5domains
from (
select client, domain, sum(bytes) as sumbytes
from log
group by client, domain
) cd
group by client
order by sum(sumbytes) desc
limit 5;