【问题标题】:How would I write this 3 level deep mysql query?我将如何编写这个 3 级深度 mysql 查询?
【发布时间】:2010-09-17 06:10:34
【问题描述】:

这可能有点难以解释,但我会尝试。

我想显示类别列表(存储在 1 个表中)以及与每个类别关联的域数(存储在另一个表中)。

在这种情况下,活动扳手是每个域都有一组与之关联的记录(存储在第三个表中)。我只想显示与它们关联的域的类别,域的计数应仅反映与它们关联的记录的域(来自第 3 个表)。

我当前的查询

SELECT r.rev_id, c.cat_id, c.cat_name, count(d.dom_id) As rev_id_count FROM reviews r
INNER JOIN  domains d ON r.rev_domain_from=d.dom_id 
INNER JOIN  categories c ON d.dom_catid=c.cat_id  
WHERE rev_status = 1
GROUP BY cat_name  
ORDER BY cat_name

这会选择正确的类别名称,但会显示错误的计数 (rev_id_count)。如果类别中有 2 个域,每个域有 2 条记录,则显示计数为 4,而应为 2。

【问题讨论】:

    标签: sql mysql


    【解决方案1】:
    SELECT Categories.Name,count(DISTINCT categories.name) FROM Categories
    JOIN Domains ON Categories.ID=Domains.CID
    JOIN Records ON Records.DID=Domains.ID
    GROUP BY Categories.Name

    使用以下设置进行测试:

    
    CREATE TABLE Categories (Name nvarchar(50), ID int  NOT NULL IDENTITY(1,1))
    CREATE TABLE Domains (Name nvarchar(50), ID int NOT NULL IDENTITY(1,1), CID int)
    CREATE TABLE Records (Name nvarchar(50), ID int NOT NULL IDENTITY(1,1), DID int)
    
    INSERT INTO Records (DID) VALUES (1)
    INSERT INTO Records (DID) VALUES (1)
    INSERT INTO Records (DID) VALUES (2)
    INSERT INTO Records (DID) VALUES (2)
    INSERT INTO Records (DID) VALUES (3)
    INSERT INTO Records (DID) VALUES (3)
    
    INSERT INTO Domains (Name,CID) VALUES ('D1',1)
    INSERT INTO Domains (Name,CID) VALUES ('D2',1)
    INSERT INTO Domains (Name,CID) VALUES ('D5',1)
    INSERT INTO Domains (Name,CID) VALUES ('D3',2)
    INSERT INTO Domains (Name,CID) VALUES ('D4',2)
    
    INSERT INTO Categories (Name) VALUES ('1')
    INSERT INTO Categories (Name) VALUES ('2')
    INSERT INTO Categories (Name) VALUES ('3')
    

    【讨论】:

      【解决方案2】:
      select c.name, count(distinct d.did) from domains d
        left join categories c on c.cid = d.cid
        left join records r on r.did = d.did
        group by c.name
      

      测试了 2 个类别,每个类别 2 个域,每个域的随机记录数。结果集:

      name     count
      ----     -----    
      test     2
      test2    2
      

      【讨论】:

        【解决方案3】:

        在AquilaX的方案上扩展,只需要选择域名即可:

        SELECT c.name, d.name, count(d.id)
          FROM categories c
            JOIN domains d ON c.id = d.cid
            JOIN records r ON r.did = d.id
        GROUP BY c.name, d.name;
        

        应该显示的内容:

        Cat 1, Domain 1, 2
        Cat 1, Domain 2, 1
        Cat 2, Domain 3, 5
        

        等等……

        (虽然没有测试)

        【讨论】:

          【解决方案4】:

          首先选择具有记录的域 - 然后提取与域匹配的类别。

          有点像

           SELECT * FROM records 
              INNER JOIN domains on <clause> 
              INNER JOIN categories on <clause>
           WHERE <something>
          

          我不能很好地解释这一点,但是在编写 SQL 时,很容易从我们想要在 select 中查看的字段列表中查看内容,并倾向于使用它来指示我们使用表的方式构建数据。事实上,我们应该更多地关注数据与我们正在构建的查询之间的关系(通常看起来是从前到后)。

          【讨论】:

          • 无效。结果与上述相同。
          【解决方案5】:

          这样的?

          SELECT c.name, count(d.id)
          FROM categories c
          JOIN domains d ON c.id = d.cid
          JOIN records r ON r.did = d.id
          GROUP BY c.name;
          

          【讨论】:

          • 这就是我现在所拥有的。它不显示域的正确计数。如果我在一个类别中有 2 个域,并且每个域有 2 条记录,它将显示计数为 4,而不是 2。
          • MySQL 是否支持 COUNT(DISTINCT)?然后尝试 COUNT(DISTINCT(d.id))。
          猜你喜欢
          • 2011-09-13
          • 2015-10-19
          • 1970-01-01
          • 2014-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多