【问题标题】:How can I make a LEFT JOIN, but with rows separed from its relations in MySQL?如何进行 LEFT JOIN,但在 MySQL 中将行与其关系分开?
【发布时间】:2021-09-11 01:49:27
【问题描述】:

我需要获取表A中的所有行,但要加入表B(基本上是LEFT JOIN),而且,我还需要获取 A 表行本身,例如,使用这些表:

表 A:

id name
1 Random name
2 Random name #2

表 B:

id parent_id location
1 2 Location #1
2 2 Location #2

使用此查询:

SELECT * FROM A
LEFT JOIN B
ON A.id = B.parent_id;

我得到这样的东西:

id name id parent_id location
1 Random name NULL NULL NULL
2 Random name #2 1 2 Location #1
2 Random name #2 2 2 Location #2

但我想得到这样的东西:

id name id parent_id location
1 Random name NULL NULL NULL
2 Random name #2 NULL NULL NULL
2 Random name #2 1 2 Location #1
2 Random name #2 2 2 Location #2

如您所见,有一行“随机名称#2”与它的连接分开,我该怎么做?

主要思想是有一个ads 表(表A),还有一个subads 表(表B)与ads 表的变化不大,我需要在唯一查询中显示所有广告和子广告。

坦克很多!

【问题讨论】:

    标签: mysql sql left-join


    【解决方案1】:

    两个建议:

    SELECT * FROM A
    INNER JOIN B
    ON A.id = B.parent_id
    UNION ALL
    SELECT *, NULL, NULL, NULL FROM A
    

    SELECT A.*,B.*
    FROM (SELECT 1 A_ONLY UNION ALL SELECT 0) A_ONLY
    CROSS JOIN A
    LEFT JOIN B
    ON A.id = B.parent_id AND NOT A_ONLY
    WHERE A_ONLY OR B.parent_id
    

    后者是一种方法,您可以在不允许使用 WITH ROLLUP 时或当您想要与产生的结果稍有不同的情况下模拟 WITH ROLLUP(此处,当没有 B 行时避免总计记录并避免双重记录)。

    【讨论】:

      【解决方案2】:

      您可以使用表 A 内容进行 INNER JOIN 而不是 LEFT JOIN 和 UNION ALL:

      两个查询必须返回相同数量的列。

      SELECT *, NULL, NULL, NULL 
      FROM A
      
      UNION ALL
      
      SELECT * 
      FROM A
      INNER JOIN B ON A.id = B.parent_id;
      

      【讨论】:

        【解决方案3】:

        您只需要 A 中添加的 NULL 行和内部 JOIN 的其余部分

        CREATE TABLE A
            (`id` int, `name` varchar(14))
        ;
            
        INSERT INTO A
            (`id`, `name`)
        VALUES
            (1, 'Random name'),
            (2, 'Random name #2')
        ;
        
        CREATE TABLE B
            (`id` int, `parent_id` int, `location` varchar(11))
        ;
            
        INSERT INTO B
            (`id`, `parent_id`, `location`)
        VALUES
            (1, 2, 'Location #1'),
            (2, 2, 'Location #2')
        ;
        
        (SELECT A.id as a_id,A.name,B.* FROM A
        INNER JOIN B
        ON A.id = B.parent_id)
        UNION
        (SELECT A.*,NULL,NULL,NULL FROM A)
        ORDER by a_id,id;
        
        a_id |姓名 |编号 | parent_id |地点 ---: | :------------- | ---: | --------: | :---------- 1 |随机名称 | | | 2 |随机名称 #2 | | | 2 |随机名称 #2 | 1 | 2 |位置 #1 2 |随机名称 #2 | 2 | 2 |位置 #2

        db小提琴here

        【讨论】:

          【解决方案4】:

          可能不是最好的实现,但在有人提出合适的解决方案之前...

          SELECT A.id, name, B.id, parent_id, location FROM A
          LEFT JOIN B
          ON A.id = B.parent_id;
          UNION ALL
          SELECT A.id, name, NULL as id, NULL as parent_id, NULL as location FROM A
          WHERE A.id IN (SELECT parent_id FROM B)
          

          只需 UNION ALL 与另一个查询从 A 中获取与 B 匹配的值,因此第一个查询中没有 NULL 值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-05-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多