我可以使用单个SQL查询执行此操作吗?

时间:2012-06-08 19:55:53

标签: php mysql sql

好的,我有一个这样的表:

id  query  results  ip
---------------------------------
1   milk   17       10.10.10.1
2   milk   17       10.10.10.1
3   milk   17       10.10.10.2
4   bread  8        10.10.10.2
5   bread  8        10.10.10.2
6   cheese 12       10.10.10.1

我现在有这个问题:

SELECT COUNT(DISTINCT(id)) as cnt, query, results, ip
FROM table
GROUP BY query
ORDER BY results ASC
LIMIT 20

此查询返回以下结果:

count  query  results
---------------------
2      bread  8
1      cheese 12
3      milk   17

我需要扩展该查询(或完全重做它)以返回类似这样的内容,最好使用嵌套数组中的IP作为查询数组的一部分:

query  count  results  ip
--------------------------------
bread  2      8        10.10.10.2 (2)
cheese 1      12       10.10.10.1 (1)
milk   3      17       10.10.10.1 (2)
                       10.10.10.2 (1)

我将使用php输出,将带有该计数的IP列表附加到查询计数显示中(单击以显示/隐藏填充了信息的模态)。

获取我需要的数据的任何方向或帮助都会很精彩!

6 个答案:

答案 0 :(得分:6)

不,你无法得到那个结果。您有两种选择:

  1. 将每个IP地址放在自己的行上,并通过PHP中的结果智能地循环。

  2. 使用GROUP_CONCAT() MySQL函数在一个字段中将IP地址连接在一起,并解析字段以在PHP中将它们分开。

答案 1 :(得分:2)

它不是嵌套数组,但你可能有类似

的东西
SELECT query, results, ip, COUNT(ip) AS cnt
FROM table
GROUP BY query, ip
ORDER BY results ASC
LIMIT 20

您在查询AND ip上分组

答案 2 :(得分:2)

这样的事情可能就是你所需要的:

SELECT COUNT(DISTINCT(id)) as cnt, query, results, ip
FROM table
GROUP BY query, ip
ORDER BY results ASC
LIMIT 20

这会给你一个像这样的结果:

query   count  results  ip
----------------------------------
bread   2      8        10.10.10.2
cheese  1      12       10.10.10.1
milk    2      17       10.10.10.1
milk    1      17       10.10.10.2

不幸的是,你不能使用嵌套数组,但这非常接近。

答案 3 :(得分:2)

group_concat()适用于此。但请记住在group_concat()中使用distinct(ip)。

以下是我试过的mysql的工作查询。

SELECT COUNT(DISTINCT(id)) as cnt, query, results, GROUP_CONCAT(DISTINCT(ip)) 
FROM table
GROUP BY query 
ORDER BY results ASC LIMIT 20;

+-----+--------+---------+----------------------------+
| cnt | query  | results | group_concat(distinct(ip)) |
+-----+--------+---------+----------------------------+
|   2 | bread  |       8 | 10.10.10.2                 |
|   1 | cheese |      12 | 10.10.10.1                 |
|   3 | milk   |      17 | 10.10.10.1,10.10.10.2      |
+-----+--------+---------+----------------------------+

当我在group_concat中运行不带distinct(ip)的查询时:

SELECT COUNT(DISTINCT(id)) as cnt, query, results, group_concat(ip) 
FROM table 
GROUP BY query 
ORDER BY results ASC LIMIT 20;

+-----+--------+---------+----------------------------------+
| cnt | query  | results | group_concat(ip)                 |
+-----+--------+---------+----------------------------------+
|   2 | bread  |       8 | 10.10.10.2,10.10.10.2            |
|   1 | cheese |      12 | 10.10.10.1                       |
|   3 | milk   |      17 | 10.10.10.1,10.10.10.1,10.10.10.2 |
+-----+--------+---------+----------------------------------+

答案 4 :(得分:2)

对此的答案(尽管有许多相反的说法)是“是的,你可以,使用派生表”:

SELECT
  SUM(cnt) as cnt,
  query, results,
  GROUP_CONCAT(ip SEPARATOR '\n') AS ip
FROM (
  SELECT
    query, results,
    COUNT(DISTINCT(id)) as cnt,
    CONCAT(ip, '(', COUNT(ip), ')') AS ip
  FROM test
  GROUP BY query, ip
) t
GROUP BY query
ORDER BY results ASC
LIMIT 20

Sample ...

不能做的一件事就是让PHP明白ip的值是一个没有其他干扰的数组。但是,您可以this slightly nasty thing将数据动态构建为JSON,然后可以将其简单地传递给PHP中的json_decode(),以便轻松将其转换为PHP矢量类型。

答案 5 :(得分:1)

试试这个:

SELECT COUNT(DISTINCT(id)) as cnt, query, results, GROUP_CONCAT(ip) AS ip
FROM table
GROUP BY query
ORDER BY results ASC
LIMIT 20

GROUP_CONCAT会将ip字段组合成逗号分隔的字符串。