Оптимизация условного объединения в MySQL, которое зависит от длины символа исходной таблицы - PullRequest
0 голосов
/ 26 апреля 2020

Я использую MySQL 5.7 и пытаюсь выполнить соединение с одной из моих исходных таблиц к справочной таблице, чтобы получить соответствующие соответствующие значения. Однако я хотел бы, чтобы объединение было условным, чтобы оно могло соответствовать в соответствии с длиной значения, найденного в исходном столбце.

Исходная таблица

|---------------------|------------------|
|     Company_Name    |     NAICS_Code   |
|---------------------|------------------|
|       Chem Inc      |        325       |
|---------------------|------------------|
|     Joe's Farming   |       1112       |
|---------------------|------------------|

Справочная таблица

|---------------------|------------------|--------------------|------------------|
| NAICS_Code_3_Digit  |     NAICS_Code_  | NAICS_Code_4_Digit |    NAICS_Cod_    | 
|                     |   3D_Description |                    |  4D_Description  |   
|---------------------|------------------|--------------------|------------------|
|        325          |   Chemicals      |       3252         |  Resin and Rubber|
|---------------------|------------------|--------------------|------------------|
|        111          | Crop Production  |       1112         | Fruit and Nuts   |
|---------------------|------------------|----------------------------------------

Финальная таблица

|---------------------|------------------|------------------|--------------------|
|     Company_Name    |     NAICS_Code   | NAICS_Code_3D_   |  NAICS_Code_4D     |     
|                     |                  |    Description   |   Description      |
|---------------------|------------------|---------------------------------------|
|       Chem Inc      |        325       |     Chemicals    |        NULL        |
|---------------------|------------------|------------------|--------------------|
|     Joe's Farming   |       1112       |  Crop Production |    Fruit and Nuts  |
|---------------------|------------------|------------------|--------------------|

Хотя я могу написать работающий запрос, он занимает очень много времени, и мне любопытно, есть ли лучший способ. Вот что я получил до сих пор:

SELECT src.Company_Name,
       src.NAICS_Code,
       CASE
           WHEN LENGTH(src.NAICS_Code < 3 THEN NULL
           ELSE ref.NAICS_Code_3D_Description
       END AS NAICS_Code_3D_Description,
       CASE
           WHEN LENGTH(src.NAICS_Code < 4 THEN NULL
           ELSE ref.NAICS_Code_4D Description
       END AS NAICS_Code_4D_Description
FROM source_table AS src
LEFT JOIN reference_table AS ref ON CASE
                                        WHEN LENGTH(src.NAICS_Code) = 4
                                             AND src.NAICS_Code = ref.NAICS_Code_4_Digit THEN 1
                                        WHEN LENGTH(src.NAICS_Code) = 3
                                             AND src.NAICS_Code = ref.NAICS_Code_3_Digit THEN 1
                                        ELSE 0
                                    END = 1;

1 Ответ

3 голосов
/ 26 апреля 2020

Может быть более эффективно дважды left join:

  • , что устраняет необходимость в сложных логиках c в предложении on в join

  • условия являются исключительными, поэтому он не будет генерировать дубликаты в наборе результатов

  • , тогда вы можете использовать coalesce() в предложении select

Итак:

select
    s.compay_name,
    s.naics_code,
    coalesce(r1.naics_code_3d_description, r2.naics_code_3d_description) naics_code_3d_description,
    r2.naics_code_4d_description
from source_table s
left join reference_table r1 on r1.naics_code_3_digit = s.naics_code
left join reference_table r2 on r2.naics_code_4_digit = s.naics_code

Если вы хотите исключить исходные строки, которые не совпадают в справочной таблице, вы можете добавить предложение where, например:

where r1.naics_code_3_digit is not null or r2.naics_code_3d_description is not null
...