我有两张桌子:
积分 - >
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;
不幸的是,当它应该是一个时,它应该只有两行,有两个点。在我的数据库中,每个项目有两个项目和一个点。请帮我解决这个问题,并了解如何改进我的查询以获得结果。
答案 0 :(得分:2)
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;
我引用the manual concerning the GROUP BY
clause:
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
除外,FETCH FIRST 30 ROWS ONLY
为{{1}}标准SQL)。
答案 1 :(得分:2)
您需要使用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
条款之间的区别非常重要。前者应用条件之前组并应用聚合,而后者应用之后。这意味着如果您想根据该计数执行条件,则必须使用HAVING
;初始示例中的WHERE
子句将在聚合之前应用,因此结果将是在给定日期之后创建的点数。
答案 2 :(得分:0)
创建一个表链接。使用字段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;
一个项目有很多要点。