MYSQL 如果父字段不为空则分组
MYSQL Group if parent field is not empty
如果父级不为空,是否可以将行分组在一起
我先解释一下数据库:
-----------------------------------------------------
ID | NAME | date | PARENT ID
-----------------------------------------------------
1 | John Doe | 2018-01-12 |
2 | Doe John | 2018-01-12 |
3 | Doe John | 2018-02-12 | 2
4 | Doe John | 2018-03-22 | 2
现在我想要的是得到这样的列表:
--------------------------------------------------------------
ID | NAME | date | PARENT ID
-------------------------------------------------------------
1 | John Doe | 2018-01-12 |
2 | Doe John | 2018-01-12 / 2018-03-22 |
我尝试过类似的东西:
SELECT *, CONCAT(parentID)
FROM names
GROUP BY parentID;
但是结果只有那些有 parentID 的,我想显示那些没有 parentID 的,并将那些有 parentID 的分组到 ID
当 parentID 为空时,您可以使用基于 ifnull 的分组依据使用 ID
SELECT *, CONCAT(parentID)
FROM names
GROUP BY ifnull(parentID, ID);
试试这个:
SELECT MAX(dates.id), MAX(dates.name), MAX(dates.date), MAX(a.date)
FROM dates
LEFT JOIN dates a ON a.parentID = dates.id
WHERE dates.parentID IS NULL GROUP BY a.parentID;
您遇到的问题是您需要一种方法来连接具有与行 ID 对应的 parentID 的行中的数据。使用此查询,我们过滤行以仅显示没有 parentID 的行,然后获取 parentID 等于当前行 ID 的所有行。使用 max 可确保正确使用 group by 并显示您的示例中似乎要求的内容。
诀窍是使用 LEFT JOIN
加入到 table 本身,使用初始 table 作为 parents 和加入的 table 作为child仁.
SELECT
*
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
A LEFT JOIN
将保留初始 table 中的所有行(在本例中为 parents)并仅添加行加入 table (children 在这种情况下)到它,如果加入是可能的。否则只会添加 NULL
个值。
| id | name | date | parent_id | id | name | date | parent_id |
| 2 | Doe John | 2018-01-12 | (null) | 3 | Bill John | 2018-02-12 | 2 |
| 2 | Doe John | 2018-01-12 | (null) | 4 | Elmo John | 2018-03-22 | 2 |
| 1 | John Doe | 2018-01-12 | (null) | (null) | (null) | (null) | (null) |
| 3 | Bill John | 2018-02-12 | 2 | (null) | (null) | (null) | (null) |
| 4 | Elmo John | 2018-03-22 | 2 | (null) | (null) | (null) | (null) |
如果这样做了,每个 parent 没有 children 就只有一行每个 parent 和 child 的行数与 children 一样多 因为 parent 存在。
因此,可以使用 parents.id
列上的 GROUP BY
,因为 parent 对每个 child 具有相同的 parent 并且每个 parent[=66 存在一行=] 没有 children。要从 parents 中筛选那些 children 而不是 parents 的人,WHERE
子句 parents.parent_id IS NULL
可以加。
SELECT
parents.id
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
WHERE
parents.parent_id IS NULL
GROUP BY
parents.id
要获得所需的 date
,您必须使用聚合函数 MIN()
and MAX()
来计算日期间隔的开始和结束日期。
函数COALESCE()
is necessary, because you might have NULL
values due to the LEFT JOIN
. It will output the first provided parameter, that is not NULL
. In this example, the result of CONCAT
is NULL
, if children.date
and therefore MIN(children.date)
and therefore LEAST(...)
returnsNULL
。在这种情况下,将使用第二个值 paprents.id
。
SELECT
parents.id,
parents.name,
COALESCE(
CONCAT(
LEAST(parents.date, MIN(children.date)),
' / ',
GREATEST(parents.date, MAX(children.date))
),
parents.date
) as 'date'
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
WHERE
parents.parent_id IS NULL
GROUP BY
parents.id,
parents.name, -- Just added for output without aggregation
parents.date -- Just added for output without aggregation
如果父级不为空,是否可以将行分组在一起
我先解释一下数据库:
-----------------------------------------------------
ID | NAME | date | PARENT ID
-----------------------------------------------------
1 | John Doe | 2018-01-12 |
2 | Doe John | 2018-01-12 |
3 | Doe John | 2018-02-12 | 2
4 | Doe John | 2018-03-22 | 2
现在我想要的是得到这样的列表:
--------------------------------------------------------------
ID | NAME | date | PARENT ID
-------------------------------------------------------------
1 | John Doe | 2018-01-12 |
2 | Doe John | 2018-01-12 / 2018-03-22 |
我尝试过类似的东西:
SELECT *, CONCAT(parentID)
FROM names
GROUP BY parentID;
但是结果只有那些有 parentID 的,我想显示那些没有 parentID 的,并将那些有 parentID 的分组到 ID
当 parentID 为空时,您可以使用基于 ifnull 的分组依据使用 ID
SELECT *, CONCAT(parentID)
FROM names
GROUP BY ifnull(parentID, ID);
试试这个:
SELECT MAX(dates.id), MAX(dates.name), MAX(dates.date), MAX(a.date)
FROM dates
LEFT JOIN dates a ON a.parentID = dates.id
WHERE dates.parentID IS NULL GROUP BY a.parentID;
您遇到的问题是您需要一种方法来连接具有与行 ID 对应的 parentID 的行中的数据。使用此查询,我们过滤行以仅显示没有 parentID 的行,然后获取 parentID 等于当前行 ID 的所有行。使用 max 可确保正确使用 group by 并显示您的示例中似乎要求的内容。
诀窍是使用 LEFT JOIN
加入到 table 本身,使用初始 table 作为 parents 和加入的 table 作为child仁.
SELECT
*
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
A LEFT JOIN
将保留初始 table 中的所有行(在本例中为 parents)并仅添加行加入 table (children 在这种情况下)到它,如果加入是可能的。否则只会添加 NULL
个值。
| id | name | date | parent_id | id | name | date | parent_id |
| 2 | Doe John | 2018-01-12 | (null) | 3 | Bill John | 2018-02-12 | 2 |
| 2 | Doe John | 2018-01-12 | (null) | 4 | Elmo John | 2018-03-22 | 2 |
| 1 | John Doe | 2018-01-12 | (null) | (null) | (null) | (null) | (null) |
| 3 | Bill John | 2018-02-12 | 2 | (null) | (null) | (null) | (null) |
| 4 | Elmo John | 2018-03-22 | 2 | (null) | (null) | (null) | (null) |
如果这样做了,每个 parent 没有 children 就只有一行每个 parent 和 child 的行数与 children 一样多 因为 parent 存在。
因此,可以使用 parents.id
列上的 GROUP BY
,因为 parent 对每个 child 具有相同的 parent 并且每个 parent[=66 存在一行=] 没有 children。要从 parents 中筛选那些 children 而不是 parents 的人,WHERE
子句 parents.parent_id IS NULL
可以加。
SELECT
parents.id
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
WHERE
parents.parent_id IS NULL
GROUP BY
parents.id
要获得所需的 date
,您必须使用聚合函数 MIN()
and MAX()
来计算日期间隔的开始和结束日期。
函数COALESCE()
is necessary, because you might have NULL
values due to the LEFT JOIN
. It will output the first provided parameter, that is not NULL
. In this example, the result of CONCAT
is NULL
, if children.date
and therefore MIN(children.date)
and therefore LEAST(...)
returnsNULL
。在这种情况下,将使用第二个值 paprents.id
。
SELECT
parents.id,
parents.name,
COALESCE(
CONCAT(
LEAST(parents.date, MIN(children.date)),
' / ',
GREATEST(parents.date, MAX(children.date))
),
parents.date
) as 'date'
FROM
users as parents
LEFT JOIN users as children ON parents.id = children.parent_id
WHERE
parents.parent_id IS NULL
GROUP BY
parents.id,
parents.name, -- Just added for output without aggregation
parents.date -- Just added for output without aggregation