如何在 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 是 Paperparent_id = 2ms1parent_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