我有两个表:
点->
id bigint(20) NO PRI NULL auto_increment
created_at datetime NO NULL
ip varchar(255) NO NULL
item_id bigint(20) NO MUL NULL
updated_at timestamp YES NULL
和项目->
id bigint(20) NO PRI NULL auto_increment
author varchar(255) NO NULL
created_at datetime NO NULL
description varchar(255) NO NULL
link varchar(255) NO NULL
source varchar(255) NO NULL
title varchar(180) NO NULL
url_encoded varchar(255) NO UNI NULL
updated_at timestamp YES NULL
我希望将它们加入一个查询中,这样我将获得item.*
以及相对于它们的总点数。我也只想对过去24小时内为其创建了任何积分的商品执行此操作。
这是我到目前为止的查询:
SELECT `items`.*, COUNT(points.item_id) as points
FROM `items`
INNER JOIN `points` ON `items`.`id` = `points`.`item_id`
WHERE `points`.`created_at` > '2013-03-16 16:00:14'
ORDER BY points DESC
LIMIT 30;
不幸的是,当我应该是两行时,它只给我一行,而当我应该是一行时,我只有两行。在我的数据库中,有两个项目,每个都有一个点。请帮助我解决此问题,并了解如何改进查询以同时获得两个结果。
您需要使用GROUP BY
来说明要基于哪些分组。如您所见,如果没有GROUP BY
,您只会得到整个结果集中的单个组。
在标准SQL中,有必要在GROUP BY
子句中包含SELECT
子句中包含的每个非聚合表达式,但是MySQL允许您不用这样做,而可以使用如下表达式。 (至少,在非严格模式下;我不确定严格模式是否会增强此要求以匹配标准SQL)
SELECT `items`.*, COUNT(1) AS points
FROM `items` INNER JOIN `points` ON `items`.`id` = `points`.`item_id`
WHERE ...
GROUP BY `items`.`id`
假设items.id
是此表的主键,因此它不会出现在items
的多行中,这应具有期望的效果。
一旦您介绍了GROUP BY
,了解WHERE
和HAVING
子句之间的区别就很重要。前者适用条件[[before组和集合,而后者适用afterafter。这意味着如果要基于该计数执行条件操作,则必须使用HAVING
;否则,必须使用WHERE
。您最初示例中的SELECT i.*, count(*) AS point_ct
FROM items i
JOIN points p ON p.item_id = i.id
GROUP BY i.id
HAVING MAX(created_at) >= DATE_SUB(CURDATE(), INTERVAL 1 day)
ORDER BY point_ct DESC
LIMIT 30;
子句将在聚合之前应用,因此结果将是在给定日期之后创建的点数。
GROUP BY
clause我引用GROUP BY
:MySQL扩展了GROUP BY
的使用,以允许选择以下字段GROUP BY
子句中未提及。如果您没有得到您希望从查询中得到的结果,请阅读说明在GROUP BY
中找到Section 12.17, “Functions and Modifiers for Use with GROUP BY Clauses”。标准SQL将要求列出
SELECT
中所有未分组的GROUP BY
项目。但是,该标准还定义自动覆盖“功能相关”列。由于我们将按主键的
id
进行分组,因此最终归结为标准SQL(LIMIT 30
除外,在标准SQL中为FETCH FIRST 30 ROWS ONLY
。
id
,itemid
,pointsid
输入:
Row1: 1, items-id1, points-id-1
Row2: 2, items-id-1, points-id-2
Row3: 3, items-id-1, points-id-3
SELECT * FROM points, field WHERE tablelink.itemid=items.id AND tablelink.pointsid=points.id;
一个项目有很多要点。