MYSQL查询查找外部连接的所有行

时间:2010-03-02 13:29:25

标签: mysql

我正在尝试创建一个查询,该查询将返回与另一个名为CHILD_CLASSES的表不匹配的表CLASSES的所有行。这两个表看起来像这样,

表CLASSES是一个自引用表,因此顶级CLASS没有parent_id。父ID行是从class_id行创建的。因此,当我将A1作为子类插入A时,其父ID为1,因为A的class_id为1.然后A11是A1的子类以及A12,因此它们的parent_id将为2.

CLASS_ID  |  PARENT_ID | CLASS_NAME
-----------------------------------
  1       |     --     |    A
  2       |     1      |    A1
  3       |     2      |    A11
  4       |     2      |    A12

然后我有另一个表CHILD_CLASSES,它将存储每个CLASS的子项。由于A是最顶级的,它将拥有它下面的所有东西的孩子,A1,A11和A12。 A1只有A11和A12。看起来像这样

ID   | PARENT_ID | CLASS_ID
----------------------------
  1  |     1     |    2
  2  |     1     |    3
  3  |     1     |    4
  5  |     2     |    3
  6  |     2     |    4

这有点过时,但我真正想要的是一个查询,它将返回CLASSES表中没有给定CLASS_ID子项的行。例如,如果我在A1上运行查询,它是class_id 2,它将返回class_ids为1的行,因为CLASS A是尚未在CHILD_CLASSES表中设置为A1的子类的CLASS。如果我在A11上运行查询,那么我会得到class_ids 1,2和4,因为A1还没有孩子,依此类推。任何帮助将非常感激。

3 个答案:

答案 0 :(得分:0)

SELECT  *
FROM    classes c
WHERE   class_id NOT IN
        (
        SELECT  class_id
        FROM    child_classes cc
        WHERE   cc.parent_id = 2
        )
        AND class_id <> 2

答案 1 :(得分:0)

Quassnoi请求的更正:

SELECT  class_id 
FROM    CLASSES c 
WHERE   c.class_id NOT IN 
        ( 
        SELECT  cc.class_id
        FROM    CHILD_CLASSES cc 
        WHERE   cc.parent_id = 2 
        ) 
        AND c.class_id <> 2 

答案 2 :(得分:0)

这可能已经三年了,但这与我今天所做的一脉相承。这里的答案对我来说根本没有帮助。因此,这是我的“外部加入”的方法。

首先,本机没有这样的东西。这就是你在这里的原因。但是,它非常简单,您不需要子查询。 (子查询会给我带来不必要的麻烦。)

  1. LEFT JOIN您要比较的两个表
  2. NULL值将显示在无法匹配的广告位中
  3. 询问价值WHERE ____ IS NULL
  4. 你的桌子没有多大意义。我认为你用“A1”而不是“A11”做了一个错字,所以为了清楚起见,我首先提供自己的错字。这是一个分层的身体部位表。

    TABLE "Body_Parts"
    
    id  |  parent  |  name
    --------------------------
    1   |   NULL   |  Torso
    2   |    1     |  Arm
    3   |    1     |  Leg
    4   |    2     |  Hand
    5   |    4     |  Finger
    

    您可能会注意到Leg目前没有孩子。好吧,只使用一个表,你可以看到哪些项目没有父项。

    SELECT *
    FROM Body_Parts AS side_A
    LEFT JOIN Body_Parts AS side_B
    ON side_A.parent = side_B.id -- bottom-up
    WHERE side_B.id IS NULL
    
    id  |  parent  |  name
    --------------------------
    1   |   NULL   |  Torso
    

    撤消ON语句会告诉您哪些项目没有子项。

    SELECT *
    FROM Body_Parts AS side_A
    LEFT JOIN Body_Parts AS side_B
    ON side_A.id = side_B.parent -- top-down
    WHERE side_B.id IS NULL
    
    id  |  parent  |  name
    --------------------------
    3   |    1     |  Leg
    5   |    4     |  Finger
    

    可以修改这两个示例,以便在两个不同的表而不是一个表上执行LEFT JOIN操作。我只想在这里说明一点。为了解决OP的陈述,

      

    这有点陈旧......

    是的,确实如此。这很臭,我认为使用两张桌子不会对你有任何好处。您可以轻松地使用一个表来跟踪每个类的一个父级。如果可能有多个父母,则根本不应该在第一个表中跟踪父母。