加入两个表mysql,一对多关系

问题描述 投票:1回答:3

我有两个表:

点->

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;

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

mysql sql join aggregate-functions
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,了解WHEREHAVING子句之间的区别就很重要。前者适用条件[[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; 子句将在聚合之前应用,因此结果将是在给定日期之后创建的点数。


2
投票
the manual concerning the 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


0
投票
创建一个表链接。使用字段iditemidpointsid

输入:

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;
一个项目有很多要点。
© www.soinside.com 2019 - 2024. All rights reserved.