首页 > 解决方案 > Mysql Left Join 3 个表和一个被加入两次

问题描述

我需要连接 3 个表。

它们都有一个 ID 值,问题是:

表格1

是主要的,名字:cnpj_cnae,ID是CNPJ_CNAE

表 2

我需要从这一列中得到四列(到这里我已经得到了)。这里的ID是CNPJ_CNAE

表3

这就是问题所在。对于表 1 上的每个 ID 值,我可以在该表上拥有超过 1 个甚至 10 个。我只需要从该表的前两列中获取 4 列。这里的ID是CNPJ_SOCIO

整理表需要看起来像

ID INFOTABLE1 INFOTABLE2 INFOTABLE3ROW1 INFOTABLE3ROW2

我已经尝试了一些连接,但是作为 mysql 的相对新手,我很痛苦 >.<

我试图这样做:

CREATE TABLE cnpj_cnae_emp_test3 AS (
SELECT 
`cnpj_cnae_test2`.*,
`cnpj_soci`.NOME_SOCIO,`cnpj_soci`.CNPJ_CPF_SOCI,`cnpj_soci`.ID_QUALIFICACAO_REP,`cnpj_soci`.DESC_QUALIFICACAO_REP,
`cnpj_emp_02`.MUNICIPIO,`cnpj_emp_02`.BAIRRO,`cnpj_emp_02`.TIPO_LOGRADOURO,`cnpj_emp_02`.LOGRADOURO,`cnpj_emp_02`.NUMERO,`cnpj_emp_02`.COMPLEMENTO
FROM `cnpj_cnae_test2`, `cnpj_soci`, `cnpj_emp_02`
WHERE `cnpj_cnae_test2`.CNPJ_CNAE = `cnpj_soci`.CNPJ_SOCIO AND `cnpj_cnae_test2`.CNPJ_CNAE = `cnpj_emp_02`.CNPJ
);

问题是这将为每个 SOCI 生成额外的行,而不是每个 SOCI 上的 1 个 soci,我需要在每行上 2 个 soci。

表 1: CNAE 表布局

表 2: EMP 表的布局

表 3: Socio 表的布局

结果表如下所示: 更详细的最终结果带有描述 的最终布局 结果布局

最后,猫头鹰的这正是我所需要的:

WITH soci_partition AS (
    SELECT CNPJ_SOCIO
    ,NOME_SOCIO
    ,CNPJ_CPF_SOCIO
    ,ID_QUALIFICACAO
    ,DESC_QUALIFICACAO_SOCIO
    ,row_number() OVER (PARTITION BY CNPJ_SOCIO ORDER BY IDX ASC) AS rownum
    FROM cnpj_soci
)

SELECT *                                    -- add actual columns
FROM cnpj_cnae_test2 AS cnae
INNER JOIN cnpj_emp_02 AS emp               -- left join instead? depends on table structure
    ON cnae.ID_CNAE = emp.IDX
LEFT JOIN soci_partition AS soci1 
    ON soci1.CNPJ_SOCIO = cnae.CNPJ_CNAE and soci1.rownum = 1
LEFT JOIN soci_partition AS soci2 
    ON soci2.CNPJ_SOCIO = cnae.CNPJ_CNAE and soci2.rownum = 2

标签: mysql

解决方案


不确定我是否正确连接/分区,外键不清楚。

即使它不完美,希望这能解释一般理论。如果您最终调试,请编辑您的正确答案。

也不要使用旧式连接。仅凭这一点,您就会立即使面试失败;它们在 25 年前被弃用。

WITH soci_partition AS (
    SELECT CNPJ_SOCIO
    ,NOME_SOCIO
    ,CNPJ_CPF_SOCIO
    ,ID_QUALIFICACAO
    ,DESC_QUALIFICACAO_SOCIO
    ,row_number() OVER (PARTITION BY CNPJ_SOCIO ORDER BY IDX ASC) AS rownum
    FROM cnpj_soci
)

SELECT *                                    -- add actual columns
FROM cnpj_cnae_test2 AS cnae
INNER JOIN cnpj_emp_02 AS emp               -- left join instead? depends on table structure
    ON cnae.ID_CNAE = emp.IDX
LEFT JOIN soci_partition AS soci1 
    ON soci1.CNPJ_SOCIO = cnae.CNPJ_CNAE and soci1.rownum = 1
LEFT JOIN soci_partition AS soci2 
    ON soci2.CNPJ_SOCIO = cnae.CNPJ_CNAE and soci2.rownum = 2

推荐阅读