簡體   English   中英

連接兩個表mysql,一對多關系

[英]Join two tables mysql, one to many relationship

我有兩個表:

積分 ->

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 ,了解WHEREHAVING子句之間的區別很重要。 前者適用於組和聚合之前的條件,而后者適用於之后 這意味着如果您想根據該計數執行條件,則必須使用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子句的手冊

MySQL 擴展了GROUP BY的使用,以允許選擇GROUP BY子句中未提及的字段。 如果您沒有從您的查詢中得到您期望的結果,請閱讀GROUP BY的說明
第 12.17 節,“與 GROUP BY 子句一起使用的函數和修飾符”

標准 SQL 需要在GROUP BY列出所有未分組的SELECT項。
但是,該標准還定義了自動涵蓋“功能相關”列。 由於我們按id分組,這是主鍵,這畢竟是標准 SQL(除了LIMIT 30 ,它在標准 SQL 中將是FETCH FIRST 30 ROWS ONLY )。

創建表鏈接。 使用字段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;

一個項目有很多點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM