2014-10-08 25 views
0

我需要显示所有类别,甚至没有项目的类别。为什么我的权利加入不起作用?

我有这个查询。

SELECT 
     i.id, 
     incident_active 'Approved', 
     incident_verified 'Verified', 
     category_title 'Category', 
     ParentCategory 'Parent Category' 
    FROM 
     incident i 
      INNER JOIN 
     incident_category ic ON i.id = ic.incident_id 
      RIGHT JOIN 
     incident_person ip ON i.id = ip.incident_id 
      RIGHT JOIN 
     (SELECT 
      c1.id, 
       c1.parent_id, 
       c2.category_title ParentCategory, 
       CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title 
     FROM 
      category c1 
     left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) AS c ON c.id = ic.category_id 
    WHERE incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH) 

其返回:

enter image description here

与此查询:

SELECT 
      c1.id, 
       c1.parent_id, 
       c2.category_title ParentCategory, 
       CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title 
     FROM 
      category c1 
     left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0 

其返回:

enter image description here

我已经多次阅读这个answer,但我不明白为什么我的右连接不起作用。

的第一个结果集应该有8个栏目,类别的列,其母公司是Protesta

UPDATE

我得到它的工作蒙山以下查询:

SELECT * FROM (SELECT 
     i.id, 
     incident_title 'Título', 
     incident_description 'Descripción', 
     incident_date 'Fecha', 
     incident_active 'Aprobado', 
     incident_verified 'Veficado', 
     person_first 'Nombres', 
     person_last 'Apellidos', 
     person_email 'Email', 
     category_id 
     -- category_title 'Categoría', 
     -- ParentCategory 'Categoría Padre' 
    FROM 
     incident i 
      INNER JOIN 
     incident_category ic ON i.id = ic.incident_id 
      RIGHT JOIN 
     incident_person ip ON i.id = ip.incident_id 

    WHERE (incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH) OR incident_dateadd IS NULL)) a 
RIGHT JOIN 

(SELECT 
      c1.id, 
       c1.parent_id, 
       c2.category_title ParentCategory, 
       CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title 
     FROM 
      category c1 
     left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) b ON a.category_id = b.id 

虽然我仍然不明白为什么它不适用于第一个版本,在我看来,这两个查询都是等价的。

如果任何人都可以解释的区别...

+4

即使您正在执行'RIGHT JOIN',您仍然在使用其他表格的列('WHERE incident_dateadd> DATE_SUB(NOW(),INTERVAL 1 MONTH)')的列上使用过滤器,在'事件'表上不存在的行 – Lamak 2014-10-08 20:25:50

+0

@Lamak我做了一个'有效'的版本,但是我仍然不清楚为什么mi第一个版本不起作用。如果您有任何意见,我很感激。 – Cesar 2014-10-08 20:44:55

+1

我有一个评论,但似乎我没有明确解释自己。所以,为了简化,让我们假设你只有'事件'和'类别'表。如果你选择了'SELECT * FROM incident RIGHT JOIN category ON ',然后在事件表** WHERE i.col1> something'的列上执行一个过滤器**,那么根据定义,当一个类别没有事件发生(因此'i.column'是'NULL'),它将被过滤掉你的结果,从而有效地消除了首先执行'RIGHT JOIN'的原因。 (另外,我讨厌'RIGHT JOIN'并且总是使用'LEFT JOIN'来代替) – Lamak 2014-10-08 20:50:49

回答

1

这是你的最后where条款的位置。

在您的第一个查询中,您拉出所有类别并将它们与一堆数据相关联,从而获得行的编译。然后使用where子句过滤掉其中的很多行,其中一些恰好是类别行。

我们来看一个简单的例子。

Table A:

X | Y 
----- 
1 | hi 
2 | bye 
3 | what 

Table B:

Z | X 
----- 
A | 1 
B | 1 
C | 2 

鉴于这些表格,如果我说了以下

SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X 

我的结果将是:

Z | X | Y 
--------- 
A | 1 | hi 
B | 1 | hi 
C | 2 | bye 
- | 3 | what 

但是,如果我在的那个结尾处添加一个where子句,所以我的查询变得

SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X WHERE B.Z > 'A' 

一些表A的被过滤掉。现在我有:

Z | X | Y 
--------- 
B | 1 | hi 
C | 2 | bye 

然而,如果我的查询会在过滤前加入,就像这样:

SELECT * FROM 
    (SELECT * FROM `B` WHERE B.Z > 'A') AS B 
RIGHT JOIN `A` ON A.X = B.X 

我的表仍包含从A所有行。

Z | X | Y 
--------- 
B | 1 | hi 
C | 2 | bye 
- | 3 | what 

这只是一个问题。在原始查询中,选择所有行然后过滤掉一些。在您的工作查询中,您首先进行过滤,然后获得所需的所有类别行。

相关问题