【问题标题】:MySQL query combining several tablesMySQL查询组合几个表
【发布时间】:2014-10-23 15:53:40
【问题描述】:

背景

为了获得我的论文数据,我必须使用一个大型的、公平的 复杂的 MySQL 数据库,包含几张表和数百 GB 的 数据。不幸的是,我是 SQL 新手,并不能真正弄清楚如何 提取我需要的数据。

数据库

数据库由我想要组合的几个表组成。这里有 相关部分:

> show tables;
+---------------------------+
| Tables_in_database        |
+---------------------------+
| Build                     |
| Build_has_ModuleRevisions |
| Configuration             |
| ModuleRevisions           |
| Modules                   |
| Product                   |
| TestCase                  |
| TestCaseResult            |
+---------------------------+

表格以下列方式链接在一起

Product ---(1:n)--> Configurations ---(1:n)--> Build

Build ---(1:n)--> Build_has_ModuleRevisions ---(n:1)--> ModuleRevision ---(n:1)--> Modules

Build ---(1:n)--> TestCaseResult ---(n:1)--> TestCase

表格的内容是

> describe Product;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| name    | varchar(255) | NO   | UNI | NULL    |                |
+---------+--------------+------+-----+---------+----------------+


> describe Configuration;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| Product_id | int(11)      | YES  | MUL | NULL    |                |
| name       | varchar(255) | NO   | UNI | NULL    |                |
+------------+--------------+------+-----+---------+----------------+


> describe Build;
+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| id               | int(11)      | NO   | PRI | NULL    | auto_increment |
| Configuration_id | int(11)      | NO   | MUL | NULL    |                |
| build_number     | int(11)      | NO   | MUL | NULL    |                |
| build_id         | varchar(32)  | NO   | MUL | NULL    |                |
| test_status      | varchar(255) | NO   |     |         |                |
| start_time       | datetime     | YES  | MUL | NULL    |                |
| end_time         | datetime     | YES  | MUL | NULL    |                |
+------------------+--------------+------+-----+---------+----------------+


> describe Build_has_ModuleRevisions;
+-------------------+----------+------+-----+---------+----------------+
| Field             | Type     | Null | Key | Default | Extra          |
+-------------------+----------+------+-----+---------+----------------+
| id                | int(11)  | NO   | PRI | NULL    | auto_increment |
| Build_id          | int(11)  | NO   | MUL | NULL    |                |
| ModuleRevision_id | int(11)  | NO   | MUL | NULL    |                |
+-------------------+----------+------+-----+---------+----------------+


> describe ModuleRevisions;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| Module_id | int(11)      | NO   | MUL | NULL    |                |
| tag       | varchar(255) | NO   | MUL |         |                |
| revision  | varchar(255) | NO   | MUL |         |                |
+-----------+--------------+------+-----+---------+----------------+


> describe Modules;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| name    | varchar(255) | NO   | UNI | NULL    |                |
+---------+--------------+------+-----+---------+----------------+


> describe TestCase;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| TestSuite_id | int(11)      | NO   | MUL | NULL    |                |
| classname    | varchar(255) | NO   | MUL | NULL    |                |
| name         | varchar(255) | NO   | MUL | NULL    |                |
| testtype     | varchar(255) | NO   | MUL | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+


> describe TestCaseResult;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| Build_id    | int(11)      | NO   | MUL | NULL    |                |
| TestCase_id | int(11)      | NO   | MUL | NULL    |                |
| status      | varchar(255) | NO   | MUL | NULL    |                |
| start_time  | datetime     | YES  | MUL | NULL    |                |
| end_time    | datetime     | YES  | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

如您所见,表格与*_id 字段相关联。例如。 TestCaseResult 通过Build_id field 链接到Build,并通过TestCase 链接到 TestCase_id 字段。

问题描述

现在我的问题。给定一个特定的 Configuration.nameProduct.name 作为 输入,我需要为每个 Build,按Build.start_time排序。

我尝试了什么

下面的查询给了我所有的Builds 给定一个Configuration.name config1Product.nameproduct1

SELECT
    *
FROM
    `database`.`Build` AS b
        JOIN
    Configuration AS c ON c.id = b.Configuration_id
        JOIN
    Product as p ON p.id = c.Product_id
WHERE
    c.name = 'config1'
        AND p.name = 'product1'
ORDER BY b.start_time;

不过,这甚至不能解决我一半的问题。现在,对于每个构建,我 需要

  1. 查找 全部 Modules 链接到 Build
    • 提取Modules.name 字段
    • 提取ModuleRevision.revision 字段
  2. 找到所有链接到BuildTestCases
    • 在哪里TestCaseResult.status = 'failure'
    • 提取链接到TestCaseResultTestCase.name 字段
  3. Build 与提取的模块名称+修订和测试用例相关联 名字
  4. 呈现Build.start_time排序的数据,以便我执行 对其进行分析。

换句话说,在所有可用数据中,我只对链接 字段Modules.nameModuleRevision.revisionTestCaseResult.statusTestCaseResult.name 到特定的Build,通过Build.start_time 订购 然后将其输出到我编写的 Python 程序中。

最终结果应该类似于

Build Build.start_time    Modules+Revisions               Failed tests
    1         20140301    [(mod1, rev1), (mod2... etc]    [test1, test2, ...]
    2         20140401    [(mod1, rev2), (mod2... etc]    [test1, test2, ...]
    3         20140402    [(mod3, rev1), (mod2... etc]    [test1, test2, ...]
    4         20140403    [(mod1, rev3), (mod2... etc]    [test1, test2, ...]
    5         20140505    [(mod5, rev2), (mod2... etc]    [test1, test2, ...]

我的问题

是否有一个好的(并且最好是高效的)SQL 查询可以提取和 提供我需要的数据?

如果没有,我完全可以提取一个或多个超集/子集 数据,以便在必要时使用 Python 解析它。但是我该如何提取 想要的数据?

【问题讨论】:

  • 顺便说一句,我怀疑Build_has_ModuleRevisions(也许还有TestCaseResult)上的代理id 列是多余的。您在这里似乎有一个完全可用的自然键。
  • 设计数据库的人声称并非如此。 :) 无论哪种方式,我都无法更改数据库的布局,我只需要从中获取数据。

标签: python mysql database


【解决方案1】:

在我看来,您需要不止一个查询。问题是Build <-> ModuleRevisionBuild <- TestCaseResult的关系基本是独立的。就架构而言,ModuleRevisions 和TestCaseResults 彼此之间并没有任何关系。您必须先查询一个,然后再查询另一个。您不能在一个查询中同时获取它们,因为结果中的每一行基本上代表“最深”相关表的一条记录(在这种情况下,ModuleRevisionTestCaseResult)包括来自其父表的任何相关信息.因此,我认为您需要以下内容:

SELECT
    M.name, MR.revision, B.id
FROM
    ModuleRevisions MR
INNER JOIN
    Modules M ON MR.Module_id = M.id
INNER JOIN
    Build_has_ModuleRevisions BHMR ON MR.id = BHMR.ModuleRevision_id
INNER JOIN
    Build B ON BHMR.Build_id = B.id
INNER JOIN
    Configuration C ON B.Configuration_id = C.id
INNER JOIN
    Product P ON C.Product_id = P.id
WHERE C.name = 'config1' AND P.name = 'product1'
ORDER BY B.start_time;

SELECT
    TCR.status, TC.name, B.id
FROM
    TestCaseResult TCR
INNER JOIN
    TestCase TC ON TCR.TestCase_id = TC.id
INNER JOIN
    Build B ON TCR.Build_id = B.id
INNER JOIN
    Configuration C ON B.Configuration_id = C.id
INNER JOIN
    Product P ON C.Product_id = P.id
WHERE C.name = 'config1' AND P.name = 'product1' and TCR.status = 'failure'
ORDER BY B.start_time;

【讨论】:

  • 您好,感谢您的回答,我想我可以处理您的查询返回的结果。但是,我需要选择 B.id 字段,以便将模块+修订结果映射到每个构建的测试用例失败。我也只对 status = "failure" 的测试用例感兴趣。我将编辑您的答案以反映这一点,但如果其中有您不同意的内容,请随时更改我的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
相关资源
最近更新 更多