3

我需要一个查询建议。

我有 3 个表,表架构如下:

clause_type:
-------------
clause_type_id  clause_type_title
--------------  ------------
1               clause type 1
2               clause type 2


clause:
-------
clause_id   clause_type_id      clause_title        position_no
---------   ------------        ------------        -----------
1           1                   clause 1            1
2           1                   clause 2            2
3           2                   clause 3            1


clause_type_link_clause:
-----------------------
clause_id   clause_type_id      position_no
---------   ------------        ------------
3           1                   3

在“clause”表列中,“clause_id”是自增列。一个子句可以有 1:N 个子句类型。所以我有第三张表“clause_type_link_clause”来维持这种 1:n 关系。如您所见,与“clause 1 & 2”一起,“clause 3”也与“clause type 1”相关联。我需要以这样的方式形成查询,即所有属于特定“clause_type”的“原因”都应该返回:

Expected result:

clause_id   clause_type_id      clause_title        position_no
---------   ------------        ------------        -----------
1           1                   clause 1            1
2           1                   clause 2            2
3           1                   clause 3            3
3           2                   clause 3            1

我尝试了某种 JOINS,但没有成功。

SELECT 
  clause_type.`clause_type_id`,
  clause.`clause_id` 
FROM
  `clause` AS clause,
  `clause_type` AS clause_type 
  LEFT JOIN `clause_type_link_clause` AS clause_type_link_clause 
    ON (
      clause_type_link_clause.`clause_type_id` = clause_type.`clause_type_id`
    ) 
WHERE clause_type.`clause_type_id` = clause.`clause_type_id`

请帮忙。

4

2 回答 2

1

您的问题是您不需要clause_type_link_clause 表来维护子句和clause_types 之间的1:n 关系。您的子句表足以满足此目的。但是,由于您有两个表,因此您可能需要一个 UNION 语句:-

SELECT DISTINCT clause_id
    FROM clause
    WHERE clause_type_id = given_clause_type_id
UNION DISTINCT
SELECT DISTINCT clause_id
    FROM clause_type_line_clause
    WHERE clause_type_id = given_clause_type_id

或类似的。

于 2013-05-23T07:34:23.937 回答
1

我个人会从您的表中删除caluse_type_id, 和,并将这些单独存储在 中,这样可以避免将类似的信息存储在两个不同的地方。position_noclauseclause_type_link_clause

要进行此转换,您可以使用:

INSERT INTO clause_type_link_clause (Clause_ID, Clause_Type_ID, Position_No)
SELECT  Clause_ID, Clause_Type_ID, Position_No
FROM    Clause
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    clause_type_link_clause
            WHERE   clause_type_link_clause.Clause_ID = Clause.Clause_ID
            AND     clause_type_link_clause.Clause_Type_ID = Clause.Clause_Type_ID
            AND     clause_type_link_clause.Position_No = Clause.Position_No
        );

ALTER TABLE Clause DROP COLUMN Clause_Type_ID;
ALTER TABLE Clause DROP COLUMN Position_No;

这将使您的架构如下:

clause:
-------
clause_id   clause_title 
---------   ------------ 
1           clause 1     
2           clause 2      
3           clause 3     


clause_type_link_clause:
-----------------------
clause_id   clause_type_id      position_no
---------   ------------        ------------
1           1                   3
2           1                   2
3           2                   1
3           1                   3

所以为了得到你想要的输出,你的查询就变成了

SELECT  Clause.Clause_ID,
        clause_type_link_clause.Clause_Type_ID,
        Clause.Clause_Title,
        clause_type_link_clause.Position_No,
        Clause_Type.clause_type_title
FROM    Clause
        INNER JOIN clause_type_link_clause
            ON clause_type_link_clause.Clause_ID = Clause.Clause_ID
        INNER JOIN Clause_Type
            ON Clause_Type.Clause_Type_ID = clause_type_link_clause.Clause_Type_ID
ORDER BY Clause.Clause_ID, clause_type_link_clause.Clause_Type_ID;

SQL Fiddle 示例

您仍然可以在没有架构更改的情况下实现此目的,如下所示:

SELECT  Clause.Clause_ID,
        ctlc.Clause_Type_ID,
        Clause.Clause_Title,
        ctlc.Position_No,
        Clause_Type.clause_type_title
FROM    Clause
        INNER JOIN 
        (   SELECT  Clause_ID, Clause_Type_ID, Position_No
            FROM    clause_type_link_clause
            UNION
            SELECT  Clause_ID, Clause_Type_ID, Position_No
            FROM    Clause
        ) ctlc
            ON ctlc.Clause_ID = Clause.Clause_ID
        INNER JOIN Clause_Type
            ON Clause_Type.Clause_Type_ID = ctlc.Clause_Type_ID
ORDER BY Clause.Clause_ID, ctlc.Clause_Type_ID;

SQL Fiddle 示例

于 2013-05-23T07:51:04.080 回答