2 votes

Fusionner deux vues non liées en une seule vue

Disons que j'ai dans ma première vue (ClothingID, Shoes, Shirts) et dans la deuxième vue, j'ai (ClothingID, Shoes, Shirts) CEPENDANT, les données n'ont aucun rapport entre elles, même le champ ID n'a aucun rapport. Je veux les combiner en une seule vue à des fins de rapport. Ainsi, la troisième vue (celle que j'essaie de créer) devrait ressembler à ceci : (ClothingID, ClothingID2, Shoes, Shoes2, Shirts, Shirts2) il n'y a donc aucun rapport, je les mets simplement côte à côte, des données sans rapport dans la même vue.

Toute aide serait fortement appréciée

3voto

Erwin Brandstetter Points 110228

Vous voulez moissonneuse-batteuse les résultats, tout en étant capable de dire aux rangs à part .
Dupliquer toutes les colonnes serait un peu exagéré. Ajouter une colonne avec des informations sur la source :

SELECT 'v1'::text AS source, clothingid, shoes, shirts
FROM   view1

UNION  ALL
SELECT 'v2'::text AS source, clothingid, shoes, shirts
FROM   view2;

2voto

Michał Powaga Points 8949
select v1.ClothingID, v2.ClothingID as ClothingID2, v1.Shoes, v2.Shoes as Shoes2,
    v1.Shirts, v2.Shirts as Shirts2
from (
    select *, row_number() OVER (ORDER BY ClothingID) AS row
    from view_1
) v1
full outer join (
    select *, row_number() OVER (ORDER BY ClothingID) AS row
    from view_2
) v2 on v1.row = v2.row

Je pense que full outer join qui joint la table en utilisant une nouvelle colonne non liée row fera l'affaire.

row_number() existe dans PostgreSQL 8.4 et plus .

Si vous avez une version inférieure que vous pouvez imiter row_number exemple ci-dessous. Cela ne fonctionnera que si ClothingID est unique en son genre.

select v1.ClothingID, v2.ClothingID as ClothingID2, v1.Shoes, v2.Shoes as Shoes2,
    v1.Shirts, v2.Shirts as Shirts2
from (
    select *, (select count(*) from view_1 t1 
        where t1.ClothingID <= t.ClothingID) as row
    from view_1 t
) v1
full outer join (
    select *, (select count(*) from view_2 t2 
        where t2.ClothingID <= t.ClothingID) as row
    from view_2 t
) v2 on v1.row = v2.row

Ajouté après le commentaire :

J'ai remarqué et corrigé l'erreur dans la requête précédente.

Je vais essayer d'expliquer un peu. Tout d'abord, nous devons ajouter un numéro de ligne aux deux vues pour nous assurer qu'il n'y a pas de vide dans les identifiants. C'est une méthode assez simple :

select *, (select count(*) from view_1 t1 
    where t1.ClothingID <= t.ClothingID) as row
from view_1 t

Cela consiste en deux choses, une simple requête sélectionnant des lignes (*) :

select *
from view_1 t

y sous-requête corrélée (en savoir plus sur wikipedia) :

(
    select count(*)
    from view_1 t1
    where t1.ClothingID <= t.ClothingID
) as row

Cela compte pour chaque ligne de la requête externe (ici c'est (*)) les lignes précédentes, y compris self. Ainsi, vous pourriez dire compter toutes les lignes qui ont ClothingID inférieur ou égal à la ligne actuelle pour chaque ligne de la vue. Pour une ClothingID (que j'ai supposé) il vous donne la numérotation des lignes (ordonnée par ClothingID ).

Exemple en direct sur data.stackexchange.com - numérotation des lignes .

Après cela, nous pouvons utiliser les deux sous-requêtes avec les numéros de ligne pour les joindre ( full outer join sur Wikipédia ), exemple en direct sur data.stackexchange.com - fusionner deux vues sans lien entre elles .

1voto

Bohemian Points 134107

Si les vues ne sont pas liées, SQL aura du mal à s'en occuper. Vous pouvez le faire, mais il y a un meilleur moyen, plus simple...

Je suggère de les fusionner l'un après l'autre plutôt que côte à côte comme vous l'avez suggéré, c'est-à-dire un syndicat plutôt qu'un rejoindre :

select 'view1' as source, ClothingID, Shoes, Shirts
from view1
union all
select 'view2', ClothingID, Shoes, Shirts
from view2

C'est l'approche habituelle pour ce type de situation, et elle est simple à coder et à comprendre.

Notez l'utilisation de UNION ALL qui conserve l'ordre des lignes sélectionnées et ne supprime pas les doublons, par opposition à UNION qui trie les lignes et supprime les doublons.

Modifié

Ajout d'une colonne indiquant de quelle vue provient la ligne.

1voto

N t Points 261

Vous pourriez utiliser Rownumber comme paramètre de jointure, et 2 tables temporaires ?

Donc quelque chose comme :

    Insert @table1
    SELECT ROW_NUMBER() OVER (ORDER BY t1.Clothing_ID ASC) [Row_ID], Clothing_ID, Shoes, Shirts)
    FROM Table1 

    Insert @table2
    SELECT ROW_NUMBER() OVER (ORDER BY t1.Clothing_ID ASC)[RowID], Clothing_ID, Shoes, Shirts)
    FROM Table2

    Select  t1.Clothing_ID, t2.Clothing_ID,t1.Shoes,t2.Shoes, t1.Shirts,t2.Shirts
    from @table1 t1
    JOIN atable2 t2 on t1.Row_ID = t2.Row_ID

Je pense que cela devrait être à peu près raisonnable. Assurez-vous que vous utilisez la bonne jointure pour que la sortie complète des deux requêtes apparaisse.

e;fb

1voto

Basavaraj Points 41

Vous pouvez essayer ce qui suit :

SELECT *
FROM (SELECT row_number() over(), * FROM table1) t1
FULL JOIN (SELECT row_number() over(), * FROM table2) t2 using(row_number)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X