1

我有两张桌子:

积分 ->

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;

不幸的是,当它应该是两个时,它只给了我一排,当它应该是一个时,它给了我两分。在我的数据库中,有两个项目,每个项目一个点。请帮我解决这个问题并了解如何改进我的查询以获得两个结果。

4

3 回答 3

3

您需要使用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之间的区别很重要。前者在应用组和聚合之前应用条件,而后者在应用之后应用。这意味着如果要根据该计数执行条件,则必须使用;初始示例中的子句将在聚合之前应用,因此结果将是在给定日期之后创建的点数。WHEREHAVINGHAVINGWHERE

于 2013-03-17T18:44:24.460 回答
2
于 2013-03-17T18:41:08.997 回答
0

创建表链接。随着领域id,,itemidpointsid

输入:

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;

一项有很多点。

于 2020-05-07T16:11:02.887 回答