如何在 SELECT 中使用 IF 和 CONCAT
How can I use IF and CONCAT within SELECT
我有这个Adjacency List Modeltable
Table:
CREATE TABLE node_structure_data (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(455) NOT NULL,
parent_id INT(10) UNSIGNED DEFAULT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES node_structure_data (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
输出:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
所以我有以下查询重复 Site 1
例如及其 children.
在这种情况下,children 是 Paper
与 parent_id = 2
和 ms1
与 parent_id = 3
INSERT INTO node_structure_data (title,parent_id)
WITH recursive max_id AS (
SELECT MAX(id) AS id FROM node_structure_data
),
child_nodes AS (
SELECT
n.id,
title,
parent_id,
m.id+1 AS new_id,
parent_id AS new_parent_id
FROM
node_structure_data n
CROSS JOIN
max_id AS m
WHERE
title='Site 1'
UNION ALL
SELECT
n.id,
n.parent_id,
n.title,
@row_num:=IF(@row_num=0,c.new_id,0) + 1 + @row_num AS new_id,
c.new_id
FROM
child_nodes c
INNER JOIN
node_structure_data n ON n.parent_id = c.id
CROSS JOIN (
SELECT @row_num:=0 AS rn
) AS vars
)
SELECT title,new_parent_id FROM child_nodes ORDER BY new_id;
输出:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
11 Site 1 1
12 Paper 11
13 ms1 12
如您所见,Site 1
及其 children 与新的唯一 id
重复。
但是,对于重复的 Site
标题,我想为重复的 Site 1
标题
添加前缀文本 Copy of
我只想要 Site/parent_id = 1
的前缀
这样重复的节点应该是这样的:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
11 Copy of Site 1 1
12 Paper 11
13 ms1 12
我尝试在查询中实现 IF 和 CONCAT,但由于某种原因,它不起作用,我没有收到任何错误,但输出保持不变。
IF(n.title LIKE '%Site%', CONCAT("Copy of ", n.title), n.title),
如果标题包含文本 Site
那么我想联系前缀和站点标题,否则没有连接。
有什么想法吗?
感谢任何帮助!!!
此解决方案展示了如何插入子树的副本并重新识别后代。
INSERT INTO node_structure_data (id, title, parent_id)
WITH RECURSIVE subtree AS (
SELECT
id,
(SELECT MAX(id) FROM node_structure_data) AS last_id,
CONCAT('Copy of ', title) AS title,
parent_id
FROM node_structure_data
WHERE id = 2 -- i.e. title = 'Site 1'
UNION ALL
SELECT
n.id,
s.last_id,
n.title,
n.parent_id
FROM subtree s
JOIN node_structure_data n ON s.id = n.parent_id
), new_id AS (
SELECT
id,
last_id + ROW_NUMBER() OVER (ORDER BY id) AS new_id,
title,
parent_id
FROM subtree
)
SELECT
n.new_id AS id,
n.title,
COALESCE(p.new_id, n.parent_id) AS parent_id
FROM new_id n
LEFT JOIN new_id p ON n.parent_id = p.id
请注意,开始 MySQL8 在表达式中设置用户变量已被弃用,并将在未来的版本中删除。
以下fiddle显示了每个CTE的结果-db<>fiddle
我有这个Adjacency List Modeltable
Table:
CREATE TABLE node_structure_data (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(455) NOT NULL,
parent_id INT(10) UNSIGNED DEFAULT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES node_structure_data (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
输出:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
所以我有以下查询重复 Site 1
例如及其 children.
在这种情况下,children 是 Paper
与 parent_id = 2
和 ms1
与 parent_id = 3
INSERT INTO node_structure_data (title,parent_id)
WITH recursive max_id AS (
SELECT MAX(id) AS id FROM node_structure_data
),
child_nodes AS (
SELECT
n.id,
title,
parent_id,
m.id+1 AS new_id,
parent_id AS new_parent_id
FROM
node_structure_data n
CROSS JOIN
max_id AS m
WHERE
title='Site 1'
UNION ALL
SELECT
n.id,
n.parent_id,
n.title,
@row_num:=IF(@row_num=0,c.new_id,0) + 1 + @row_num AS new_id,
c.new_id
FROM
child_nodes c
INNER JOIN
node_structure_data n ON n.parent_id = c.id
CROSS JOIN (
SELECT @row_num:=0 AS rn
) AS vars
)
SELECT title,new_parent_id FROM child_nodes ORDER BY new_id;
输出:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
11 Site 1 1
12 Paper 11
13 ms1 12
如您所见,Site 1
及其 children 与新的唯一 id
重复。
但是,对于重复的 Site
标题,我想为重复的 Site 1
标题
添加前缀文本 Copy of
我只想要 Site/parent_id = 1
这样重复的节点应该是这样的:
id title parent_id
1 Division NULL
2 Site 1 1
3 Paper 2
4 ms1 3
5 Site 2 1
6 Paper 5
7 ms2 6
8 Site 3 1
9 Paper 8
10 ms3 9
11 Copy of Site 1 1
12 Paper 11
13 ms1 12
我尝试在查询中实现 IF 和 CONCAT,但由于某种原因,它不起作用,我没有收到任何错误,但输出保持不变。
IF(n.title LIKE '%Site%', CONCAT("Copy of ", n.title), n.title),
如果标题包含文本 Site
那么我想联系前缀和站点标题,否则没有连接。
有什么想法吗?
感谢任何帮助!!!
此解决方案展示了如何插入子树的副本并重新识别后代。
INSERT INTO node_structure_data (id, title, parent_id)
WITH RECURSIVE subtree AS (
SELECT
id,
(SELECT MAX(id) FROM node_structure_data) AS last_id,
CONCAT('Copy of ', title) AS title,
parent_id
FROM node_structure_data
WHERE id = 2 -- i.e. title = 'Site 1'
UNION ALL
SELECT
n.id,
s.last_id,
n.title,
n.parent_id
FROM subtree s
JOIN node_structure_data n ON s.id = n.parent_id
), new_id AS (
SELECT
id,
last_id + ROW_NUMBER() OVER (ORDER BY id) AS new_id,
title,
parent_id
FROM subtree
)
SELECT
n.new_id AS id,
n.title,
COALESCE(p.new_id, n.parent_id) AS parent_id
FROM new_id n
LEFT JOIN new_id p ON n.parent_id = p.id
请注意,开始 MySQL8 在表达式中设置用户变量已被弃用,并将在未来的版本中删除。
以下fiddle显示了每个CTE的结果-db<>fiddle