Выберите, чтобы заполнить пустые поля, используя идентификатор и значения того же столбца - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть таблица, подобная этой:

  PK |  IDs | name1 | name2
    -------------------
   1 |  1   |  a    | null  
   2 |  1   |  a    |  x
   3 |  2   |  b    | null  
   4 |  3   |  c    |  z
   5 |  2   | null  |  y
   6 |  1   | null  |  x
   7 |  2   |  b    | null
   8 |  2   | null  | null

И я хочу выполнить выборку в mySQL, которая выдаст мне такой вывод:

  PK |  IDs | name1 | name2
    -------------------
   1 |  1   |  a    |  x
   2 |  1   |  a    |  x
   3 |  2   |  b    |  y
   4 |  3   |  c    |  z
   5 |  2   |  b    |  y
   6 |  1   |  a    |  x
   7 |  2   |  b    |  y
   8 |  2   |  b    |  y

Так что все строки с одним и тем же идентификатором имеют одинаковые name1 и name2, проверяя ту, которая не является нулевой, чтобы заполнить ее, если ее нет, она будет продолжаться как нулевая.

Ответы [ 3 ]

1 голос
/ 15 апреля 2020

Если у вас есть только одно значение name1 или name2 для данного значения ID, вы можете использовать функцию агрегирования, например MAX (или MIN), которая даст вам это значение из всех значение для этого IDs в таблице. Используя производную таблицу с этими значениями, вы можете JOIN перейти к исходной таблице, чтобы получить значения name1 и name2 для каждой комбинации PK, IDs:

SELECT d.PK, d.IDs, m.name1, m.name2
FROM data d
JOIN (SELECT IDs, MAX(name1) AS name1, MAX(name2) AS name2
      FROM data
      GROUP BY IDs) m ON m.IDs = d.IDs

Вывод:

PK  IDs     name1   name2
1   1       a       x
2   1       a       x
3   2       b       y
4   3       c       z
5   2       b       y
6   1       a       x
7   2       b       y
8   2       b       y

Демонстрация по SQLFiddle

0 голосов
/ 15 апреля 2020

Вы можете использовать коррелированный подзапрос:

select t.pk, t.ids,
       coalesce(t.name1, (select t1.name1 
                          from table t1 
                          where t1.pk < t.pk and t1.name1 is not null 
                          order by t1.pk desc 
                          limit 1)
                ) as name1,
       coalesce(t.name2, (select t1.name2 
                          from table t1 
                          where t1.pk < t.pk and t1.name2 is not null 
                          order by t1.pk desc 
                          limit 1)
                ) as name2
from table t;
0 голосов
/ 15 апреля 2020

Вы можете использовать update с join:

update t join
       (select id, max(name1) as name1, max(name2) as name2
        from t
        group by id
       ) tt
       on t.id = tt.id
    set t.name1 = coalesce(t.name1, tt.name1),
        t.name2 = coalesce(t.name2, tt.name2)
    where t.name1 is null or t.name2. is null;

Примечание. Это не изменит значения, отличные от NULL, поэтому это безопасно, даже если значения отличаются для данного id.

...