SQL - 加入3个表格有点混乱

时间:2014-12-07 20:17:00

标签: mysql sql join group-by distinct

我需要一个有点令人困惑的SQL查询的帮助。我有3张桌子。名称:文章类别 category_article 表。

在我的文章表中,共有4列:

  1. 援助 - >文章ID
  2. py - >文章年份
  3. totalPoint - >文章
  4. tc - >引用数量
  5. 在类别表中,有两列是:

    1. cid - >类别ID
    2. 类别 - >类别名称
    3. 最后,在我的category_article表中,有两列是:

      1. cid - >类别ID
      2. 援助 - >与类别相关的文章ID
      3. 在下面,有样本表输入。

        文章表

        ______________________________
        | 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种不同的类别年组合。 第二种方式 - >显示相同的值timecited文章,但我必须看到20个不同的类别 - 年组合。

        enter image description here

1 个答案:

答案 0 :(得分:2)

这有点棘手,因为你在这里尝试做很多不同的事情。我会简单地将它们分解并重新组合在一起。首先,如果要将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,但是现在它应该给你你想要的东西,因为你的表被编入索引它不应该运行得太慢。