J'ai besoin d'un moyen de gérer le scénario suivant.
Rédigez une requête pour transformer l'ensemble de résultats suivant
select t.CADID, t.TECHNOLOGYTYPE, t.ACCESSSUPPLIER, t.LOCATION, t.LOCATIONTYPE, t.NETWORKTYPE, t.ACCESSTYPE, t.CARRIERTYPE, t.MAXDOWNSPEED, t.MAXUPSPEED, v.NAME, v.VALUE
from( TableA t
LEFT OUTER JOIN TableB VIEW0 ON (VIEW0.access_supplier = t.access_supplier
AND VIEW0.network_type = t.network_type
AND VIEW0.address_location_type_map_id = t.address_location_type_map_id
AND VIEW0.NAME = 'Nls-type')
LEFT OUTER JOIN TableB VIEW1 ON (VIEW1.access_supplier = t.access_supplier
AND VIEW1.network_type = t.network_type
AND VIEW1.address_location_type_map_id = t.address_location_type_map_id
AND VIEW1.NAME = 'NL-type')
LEFT OUTER JOIN TableB VIEW2 ON (VIEW2.access_supplier = t.access_supplier
AND VIEW2.network_type = t.network_type
AND VIEW2.address_location_type_map_id = t.address_location_type_map_id
AND VIEW2.NAME = 'Net-type')
LEFT OUTER JOIN TableB VIEW3 ON (VIEW3.access_supplier = t.access_supplier
AND VIEW3.network_type = t.network_type
AND VIEW3.address_location_type_map_id = t.address_location_type_map_id
AND VIEW3.NAME = 'Interconnect-level')
LEFT OUTER JOIN TableB VIEW4 ON (VIEW4.access_supplier = t.access_supplier
AND VIEW4.network_type = t.network_type
AND VIEW4.address_location_type_map_id = t.address_location_type_map_id
AND VIEW4.NAME = 'FTU-type')
LEFT OUTER JOIN TableB VIEW5 ON (VIEW5.access_supplier = t.access_supplier
AND VIEW5.network_type = t.network_type
AND VIEW5.address_location_type_map_id = t.address_location_type_map_id
AND VIEW5.NAME = 'Area-type')
)WHERE (t.cad_id = '237864868')
cross apply
(values ('a', VIEW0.name as name0, VIEW0.value as vaue0),
('b', VIEW1.name as name1, VIEW1.valueb as value1),
('c', VIEW2.name as name2, VIEW2.valuec as value2),
('d', VIEW3.name as name3, VIEW3.valued as value3)
) v(which, name, value)
where v.name is not null or
(v.which = 'a' and
v.name0 is null and v.name1 is null and v.name2 is null and v.name3 is null
);
... en celui-ci
ID|Location|Name |Value | __|________|_____|______| 0 | BL |NULL |NULL | __|________|_____|______| 1 | GT |x |y | __|________|_____|______| 1 | GT |s |z | __|________|_____|______| 2 | SZ |c |d | _|________|_____|______| 2 | SZ |e |f |
MODIFIER: J'ai décidé d'utiliser votre option d'application croisée, mais j'ai du mal à l'implémenter, Je vais coller ma requête d'origine avec les noms de table modifiés pour que Gordon ou quelqu'un d'autre puisse m'aider.
ID|Location|NameA|ValueA|NameB|ValueB|NameC|ValueC|NameD|ValueD| __|________|_____|______|_____|______|_____|______|_____|______| 0 | BL |NULL |NULL |NULL |NULL |NULL |NULL |NULL |NULL | __|________|_____|______|_____|______|_____|______|_____|______| 1 | GT |x |y |NULL |NULL |s |z |NULL |NULL | __|________|_____|______|_____|______|_____|______|_____|______| 2 | SZ |c |d |e |f |NULL |NULL |NULL |NULL | __|________|_____|______|_____|______|_____|______|_____|______|
4 Réponses :
Utilisez simplement UNION , comme ci-dessous:
select ID,Location,NameA,ValueA from table where NameA is not null union select ID,Location,NameB,ValueB from table where NameB is not null union select ID,Location,NameC,ValueC from table where NameC is not null union select ID,Location,NameD,ValueD from table where NameD is not null union select ID,Location,null,null from table where coalesce(NameA,NameB,NameC,NameD) is null
Ou vous pouvez utiliser UNPIVOT comme suit:
-- Sample Data:
WITH dat(ID,Location,NameA,ValueA,NameB,ValueB,NameC,ValueC,NameD,ValueD) AS
(SELECT 0 , 'BL' ,NULL ,NULL ,NULL ,NULL,NULL ,NULL,NULL ,NULL FROM dual
UNION
SELECT 1 , 'GT' ,'x' ,'y' ,NULL ,NULL,'s' , 'z',NULL ,NULL FROM dual
UNION
SELECT 2 , 'SZ' ,'c' ,'d' ,'e' ,'f' ,NULL ,NULL,NULL ,NULL FROM dual)
-- SQL-Statement:
SELECT id,location, NAME, VALUE
FROM (
SELECT id,location, NAME, VALUE,sk, MAX(NAME) over (PARTITION BY id) max_name
FROM dat
UNPIVOT INCLUDE NULLS(
(NAME, VALUE) FOR sk IN ((NameA, ValueA) AS 1
,(NameB, ValueB) AS 2
,(NameC, ValueC) AS 3
,(NameD, ValueD) AS 4)
)
)
WHERE (SK = 1 AND max_name IS NULL)
OR NAME IS NOT NULL
declare @tempTbl table ([ID] int, [Location] nvarchar(10), [Name] nvarchar(10), [Value] nvarchar(10));
insert into @tempTbl
select [ID],[Location],[Name], [Value] From
(
SELECT [ID],[Location],[NameA] as [Name],[ValueA] as [Value] FROM [dbo].[LocationTbl]
UNION
SELECT [ID],[Location],[NameB],[ValueB] FROM [dbo].[LocationTbl]
UNION
SELECT [ID],[Location],[NameC],[ValueC] FROM [dbo].[LocationTbl]
UNION
SELECT [ID],[Location],[NameD],[ValueD] FROM [dbo].[LocationTbl]
) as X
where [Name] is not null AND [Value] is not null
select * from @tempTbl
UNION
SELECT [ID], [Location], Null as [Name], Null as [Value]
FROM [dbo].[LocationTbl]
WHERE [Location] not in (select [Location] from @tempTbl)
order by [ID];
try this.
La réponse la plus simple dans Oracle est probablement:
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
);
Pour certains (raison probablement absurde), j'ai fourni la réponse ci-dessous en pensant que la question était étiquetée SQL Server. Oracle 12C prend en charge les jointures latérales, donc ce qui suit pourrait être adapté à la syntaxe Oracle.
Je laisse le reste de la réponse ici.
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);
I aime décomposer en utilisant cross apply . Donc, le décompressé de base est:
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);
Vous voulez alors une condition que null n'apparaisse qu'une seule fois si c'est tout le valeurs. Vous pouvez utiliser les fonctions de fenêtre pour cela:
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
);
Je ne sais pas si vous vous souciez simplement de savoir si nom est NULL code > ou si vous voulez que nom et valeur soient NULL . L'une ou l'autre logique peut être mise en œuvre; on ne sait tout simplement pas ce que vous voulez.
EDIT:
Vous pouvez également le faire sans sous-requête:
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 ;
Ceci est probablement la manière la plus simple d'écrire la logique.
Je n'ai pas remarqué votre réponse, je vais essayer maintenant. Et pour répondre à votre question, dans la requête d'origine, VALUE ne sera jamais nulle, donc je me soucie seulement de savoir si toutes les colonnes NAME / VALUE d'un enregistrement sont nulles, pour renvoyer un enregistrement NULL et non celui de chaque paire NAME / VALUE. J'ai des problèmes à cause d'une requête originale complexe que j'ai, ce qui rend les choses un peu difficiles.
@T_Dejan. . . Pour une raison quelconque, la réponse originale était pour SQL Server (évidemment j'ai mal lu ou ignoré les balises sur la question). J'ai fourni une réponse compatible avec Oracle.
Pouvez-vous jeter un oeil, j'ai édité la question. J'ai essayé avec l'option de sous-requête et d'application croisée, mais j'ai du mal à l'implémenter. Est-ce possible dans Oracle?
@T_Dejan. . . Créez un CTE avec votre requête ( avec t comme (...) ), puis utilisez la première version avec union all .
@T_Dejan. . . Y a-t-il une raison pour laquelle vous n'avez pas accepté la réponse? Quelle version d'Oracle utilisez-vous?
Annuler le pivot? oracle.com/technetwork/articles/sql/11g-pivot- 097235.html