Самый простой ответ в Oracle, вероятно, таков:
select t.id, t.namea as name. t.valuea as valuea
from t
where t.namea is not null or
(t.namea is null and t.nameb is null and t.namec is null and t.named is null)
union all
select t.id, t.nameb as name. t.valueb as valuea
from t
where t.nameb is not null
union all
select t.id, t.namec as name. t.valuec as valuea
from t
where t.namec is not null
union all
select t.id, t.named as name. t.valued as valuea
from t
where t.named is not null ;
По некоторым (возможно, абсурдным причинам) я предоставил ответ ниже, думая, что вопрос был помечен как SQL Server.Oracle 12C поддерживает боковые объединения, поэтому приведенный ниже текст может быть адаптирован к синтаксису Oracle.
Здесь я оставляю остаток ответа.
select t.id, v.name, v.value
from t cross apply
(values ('a', t.namea, t.valuea),
('b', t.nameb, t.valueb),
('c', t.namec, t.valuec),
('d', t.named, t.valued)
) v(which, name, value)
where v.name is not null or
(v.which = 'a' and
);
Мне нравится отключать, используя cross apply
,Таким образом, основной разворот:
select t.id, v.name, v.value
from t cross apply
(values (t.namea, t.valuea), (t.nameb, t.valueb), (t.namec, t.valuec), (t.named, t.valued)
) v(name, value);
Затем вы хотите условие, что null
появляется только один раз, если это все значения.Для этого вы можете использовать оконные функции:
select id, name, value
from (select t.id, v.name, v.value,
count(*) over (partition by t.id, v.name, v.value) as cnt_nv,
row_number() over (order by t.id) as seqnum
from t cross apply
(values (t.namea, t.valuea), (t.nameb, t.valueb), (t.namec, t.valuec), (t.named, t.valued)
) v(name, value)
) v
where name is not null or
(cnt_nv = 4 and seqnum = 1);
Мне немного неясно, просто вас волнует, является ли name
NULL
или вы хотите, чтобы name
и value
были NULL
.Любая логика может быть реализована;просто неясно, какой вы хотите.
РЕДАКТИРОВАТЬ:
Вы также можете сделать это без подзапроса:
select t.id, v.name, v.value
from t cross apply
(values ('a', t.namea, t.valuea),
('b', t.nameb, t.valueb),
('c', t.namec, t.valuec),
('d', t.named, t.valued)
) v(which, name, value)
where v.name is not null or
(v.which = 'a' and
t.namea is null and t.nameb is null and t.namec is null and t.named is null
);
Это, вероятно, самый простой способ написать логику.