【问题标题】:SQL - Join 3 tables little confusingSQL - 加入 3 个表有点混乱
【发布时间】:2014-12-07 20:17:00
【问题描述】:

我需要关于一个有点混乱的 sql 查询的帮助。我有 3 张桌子。名称:articlecategorycategory_article 表。

在我的文章表中,有 4 列分别是:

  1. aid -> 文章 ID
  2. py -> 文章年份
  3. totalPoint -> 文章点数
  4. tc -> 文章被引用次数

在类别表中,有 2 列分别是:

  1. cid -> 类别 ID
  2. 类别 -> 类别名称

最后,在我的 category_article 表中,有 2 列分别是:

  1. cid -> 类别 ID
  2. aid -> 与类别相关的文章 ID

在下面,有示例表输入。

文章列表

______________________________
| aid | py | totalPoint | tc |
-------------------------------
| 1   | 2014| 30        | 3   |
-------------------------------
| 2   | 2013| 20        | 2   |
-------------------------------
| 3   | 2014| 50        | 10   |
_______________________________

分类表

__________________
| cid | category   |
-------------------
| 1   | Surgery    | 
------------------- 
| 2   |  Enginering| 
____________________

Category_Article 表

__________________
| cid | aid       |
-------------------
| 1   | 3         | 
------------------- 
| 2   |  5        | 
____________________

我的目的是只用一个 sql 查询找到这个输出。

类别名称、年份、totalArticleNumber、totalPoint(desc)、文章 id(当年和该类别中被引用次数最多的文章)、被引用时间(前 20 名)

示例输出为:

_______________________________________________________________________________________    
Category name | year | totalArticleNumber | totalPoint | id of article(best) | citedTime    |
________________________________________________________________________________________
   Surgery    | 2013 |     182            |    5234    |     312             |   22         | 
_________________________________________________________________________________________
   Engineering | 2014 |     189          |     5000    |      10             |    32        |

我可以用 java 编程语言来做这个表。就像首先做一些查询,然后做第二个查询。

但我需要在一个查询中完成。

我尝试使用JOINHAVINGGROUP BYDISTINCT 和其他一些 sql 内容,但我无法成功。

感谢任何帮助。

编辑

例如,如果有两篇文章具有相同的时间被引值,则将它们一起显示。 与前两列一样,文章 419 和 385 的引用值相同,因此它们都在表中。 我有两个选择。

第一种方式 -> 只显示一篇文章并限制 20 个。所以通过这种方式我可以看到 20 个不同的类别-年份组合。 第二种方式-> 显示相同价值的被引用文章,但我必须看到 20 个不同的类别-年份组合。

【问题讨论】:

  • citedTime 代表什么?您如何确定最佳文章?
  • @McAdam331citedTime 是文章的被引次数。引用时间的值决定了文章是否最好。
  • 听起来不错,我现在正在输入内容。

标签: mysql sql join group-by distinct


【解决方案1】:

这有点棘手,因为您在这里尝试做很多不同的事情。我会简单地将它们分解并重新组合在一起。首先,如果要将JOIN所有的表放在一起,可以使用如下语法:

SELECT *
FROM article a
JOIN category_article ca ON ca.aid = a.aid
JOIN category c ON c.cid = ca.cid;

现在,这将只显示分配到某个类别的文章。也就是说,如果某篇文章在 category_article 表中不存在,或者某个类别在 category_article 表中不存在,则不会出现在此处。

如果要获取一个类别每年的文章总数,可以使用 COUNT(*) 聚合函数,以及 SUM() 函数获取该类别的总分,然后按类别分组和年份来获得该组的金额:

SELECT c.category, a.py, COUNT(*) AS numArticles, SUM(totalPoint) AS totalPoints
FROM article a
JOIN category_article ca ON ca.aid = a.aid
JOIN category c ON c.cid = ca.cid
GROUP BY c.cid, a.py;

接下来,必须使用子查询来获得最佳文章。我建议暂时只关注那个子查询。您可以编写一个查询来获取每个类别和年份的 MAX tc,然后将其与您的表连接以获取所有匹配条件,如下所示:

SELECT c.category, a.*
FROM category c
JOIN category_article ca ON c.cid = ca.cid
JOIN article a ON a.aid = ca.aid
JOIN(
  SELECT c.cid, a.py, MAX(a.tc) AS maxCited
  FROM category c
  JOIN category_article ca ON ca.cid = c.cid
  JOIN article a ON a.aid = ca.aid
  GROUP BY c.cid, a.py) temp ON temp.cid = c.cid AND temp.py = a.py AND temp.maxCited = a.tc;

一旦你有了它,你就可以用上面的查询加入那个子查询,以在其他组信息旁边显示最好的文章信息。

SELECT temp1.category, temp1.py, temp1.numArticles, temp1.totalPoints, temp2.aid AS bestArticle, temp2.tc AS citedTime
FROM(
  SELECT c.category, a.py, COUNT(*) AS numArticles, SUM(totalPoint) AS totalPoints
  FROM article a
  JOIN category_article ca ON ca.aid = a.aid
  JOIN category c ON c.cid = ca.cid
  GROUP BY c.cid, a.py) temp1
JOIN(
  SELECT c.category, a.*
  FROM category c
  JOIN category_article ca ON c.cid = ca.cid
  JOIN article a ON a.aid = ca.aid
  JOIN(
    SELECT c.cid, a.py, MAX(a.tc) AS maxCited
    FROM category c
    JOIN category_article ca ON ca.cid = c.cid
    JOIN article a ON a.aid = ca.aid
    GROUP BY c.cid, a.py) temp ON temp.cid = c.cid AND temp.py = a.py AND temp.maxCited = a.tc) temp2
  ON temp1.category = temp2.category AND temp1.py = temp2.py;

这是一个SQL Fiddle 示例。我将尝试如何使用更少的 JOINS,但现在它应该可以满足您的需求,并且由于您的表已编入索引,因此它不应该运行得太慢。

【讨论】:

  • 感谢您的帮助和努力。就像你说的,我尝试在一个查询中做很多事情,所以这很难。但是有一些误解,或者我无法正确解释。每一年,最好的文章都应该放在一个类别中。
  • 如果你有不明白的地方,或者有什么不对的地方,试着解释一下,我会尽力帮助你的。
  • 工程(类别)| 2009(年) | 55(numAritc) | 1843.13(总点数) | 385(最佳文章ID)| 9(最佳文章被引时间)它不应该是同一年的另一个工程类别。
  • 我希望我现在解释得更清楚,否则我可以编辑问题区域的底部。
  • 你是说你在 2009 年获得了两排工程?
猜你喜欢
  • 2013-11-29
  • 2018-08-04
  • 2021-03-05
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2015-10-18
相关资源
最近更新 更多