1

我需要显示所有类别,甚至是没有项目的类别。

我有这个查询。

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)

返回:

在此处输入图像描述

这个查询:

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

返回:

在此处输入图像描述

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

第一个结果集应该还有 8 列,父类别的列Protesta

更新

我通过以下查询使其工作:

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

1 回答 1

2

这是你最后一个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

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

于 2014-10-08T21:01:14.490 回答