我需要显示所有类别,甚至是没有项目的类别。
我有这个问题。
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
返回:
我已多次阅读此answer但我无法理解为什么我的正确加入无效。
第一个结果集应该有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
虽然我仍然不明白为什么它不能使用第一个版本,但在我看来这两个查询都是等价的。
如果有人能解释这些差异......
答案 0 :(得分: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
这只是一个有序的问题。在原始查询中,选择所有行,然后过滤掉一些行。在您的工作查询中,首先进行过滤,然后获得所需的所有类别行。