Résultats de l'Union choisit dans SQL Server
-
23-08-2019 - |
Question
Est-il possible d'UNION requêtes à partir des tables ou des vues qui n'ont aucun résultat en commun? Ce que je suis en train de faire est de combiner des données de différentes vues en un seul résultat. J'ai
select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3
Je souhaite que le résultat soit a, b, z, c. Est-ce où j'utiliser select à partir? Qu'est-ce que ça ressemble?
select ? from (
select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3)
J'utilise MS SQL Server et les vues n'ont pas les clés primaires. Merci beaucoup.
La solution
Si je comprends bien votre question, vous obtenez probablement des résultats comme ceci:
a1, b1, null, c1
a2, b2, null, c2
a3, b2, null, c3
null, null, z1, null
null, null, z2, null
null, null, z3, nul
l
.. mais ce que vous essayez d'obtenir des résultats comme celui-ci:
a1, b1, z1, c1
a2, b2, z2, c2
a3, b2, z3, c3
Si je comprends bien le problème?
Si cela est correct, vous aurez besoin d'avoir un moyen de se joindre à ces sous-requêtes ensemble, de sorte que vous pouvez dire que le SQL 1 y ensemble, et les 2 y ensemble, et ainsi de suite.
Autres conseils
A concatène union des jeux de résultats, il ne les combine pas.
Alors, que vous obtiendrez de votre première requête est la suivante:
a b (null) c
(null) (null) z (null)
Si vous voulez les combiner, vous aurez à les rejoindre, et vous devez avoir quelque chose en commun, ou vous devrez combiner les données dans le programme.
Avez-vous seulement 1 rang de chacun?
Si oui, alors si le modèle ci-dessus va toujours être comme ça, cela fonctionnerait:
SELECT SQ1.a, SQ1.b, SQ2.z, SQ1.c
FROM (
SELECT 1 k, View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a) SQ1
INNER JOIN (
SELECT 1 k, NULL a, NULL b, z, NULL c
FROM View3) SQ2 ON SQ1.k = SQ2.k
Cependant, si vous ne savez pas si View3.a a une valeur ou View1.a a une valeur, et que vous voulez une de la première requête s'il y a une valeur 3, alors cela fonctionne:
SELECT COALESCE(SQ1.a, SQ2.a) a, COALESCE(SQ1.b, SQ2.b) b,
COALESCE(SQ1.z, SQ2.z) z, COALESCE(SQ1.c, SQ2.c) c
FROM (
SELECT 1 k, View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a) SQ1
INNER JOIN (
SELECT 1 k, NULL a, NULL b, z, NULL c
FROM View3) SQ2 ON SQ1.k = SQ2.k
Mais, et il y a un grand mais ici. Si vous avez plus d'une ligne dans l'une des vues, vous allez finir avec les données qui ne vont pas ensemble. Dans ce cas, vous doivent ont quelque chose en commun.
Voici le code complet que j'ai essayé, ainsi que les résultats:
USE master
GO
DROP DATABASE TestDB
GO
CREATE DATABASE TestDB
GO
USE TestDB
GO
CREATE TABLE View1
(
a INT,
b INT,
c INT
)
GO
CREATE TABLE View2
(
a INT,
z INT
)
GO
CREATE TABLE View3
(
z INT
)
GO
INSERT INTO View1 (a, b, c) VALUES (10, 20, 30)
GO
INSERT INTO View2 (a, z) VALUES (10, 40)
GO
INSERT INTO View3 (z) VALUES (50)
GO
SELECT View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a
UNION
SELECT NULL a, NULL b, z, NULL c
FROM View3
SELECT SQ1.a, SQ1.b, SQ2.z, SQ1.c
FROM (
SELECT 1 k, View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a) SQ1
INNER JOIN (
SELECT 1 k, NULL a, NULL b, z, NULL c
FROM View3) SQ2 ON SQ1.k = SQ2.k
SELECT COALESCE(SQ1.a, SQ2.a) a, COALESCE(SQ1.b, SQ2.b) b,
COALESCE(SQ1.z, SQ2.z) z, COALESCE(SQ1.c, SQ2.c) c
FROM (
SELECT 1 k, View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a) SQ1
INNER JOIN (
SELECT 1 k, NULL a, NULL b, z, NULL c
FROM View3) SQ2 ON SQ1.k = SQ2.k
Résultats:
a b z c
----------- ----------- ----------- -----------
NULL NULL 50 NULL
10 20 NULL 30
(2 row(s) affected)
a b z c
----------- ----------- ----------- -----------
10 20 50 30
(1 row(s) affected)
a b z c
----------- ----------- ----------- -----------
10 20 50 30
(1 row(s) affected)
Si vous ajoutez une ligne unique à View3, comme ceci:
INSERT INTO View3 (z) VALUES (51)
Ensuite, vous obtiendrez ces résultats, notez les lignes doublées:
a b z c
----------- ----------- ----------- -----------
NULL NULL 50 NULL
NULL NULL 51 NULL
10 20 NULL 30
(3 row(s) affected)
a b z c
----------- ----------- ----------- -----------
10 20 50 30
10 20 51 30
(2 row(s) affected)
a b z c
----------- ----------- ----------- -----------
10 20 50 30
10 20 51 30
(2 row(s) affected)
Si je comprends: vous essayez de « l'effondrement » de vos résultats et de se débarrasser de tous les NULLs? Si oui, ne jamais résulter de view3 correspondent à un résultat de View1 / view2? Si oui, quelle est la relation? Sinon, faites-le nombre de résultats au moins match?
Pour plusieurs enregistrements, approche ROW_NUMBER () a fonctionné pour moi. L'approche Sélectionnez 1 k était de retour d'un produit cartésien.
SELECT SQ1.a, SQ1.b, SQ2.z, SQ1.c
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY a) k, View1.a, b, NULL z, c
FROM View1 INNER JOIN View2 ON View1.a = View2.a) SQ1
INNER JOIN (
SELECT ROW_NUMBER() OVER (ORDER BY b) k, NULL a, NULL b, z, NULL c
FROM View3) SQ2 ON SQ1.k = SQ2.k
Peut-être que vous cherchez quelque chose comme ça? (Juste une supposition sauvage)
SELECT
VIEW1.a,
VIEW1.b,
(SELECT TOP 1 z FROM VIEW3) AS z,
VIEW2.c
FROM
VIEW1, VIEW2
WHERE
VIEW1.a = VIEW2.a
Les résultats de toute sql sélectionner, y compris une union, sont un ensemble statique de colonnes. (Pas de polymorphisme.)
Mais vous ne devez pas utiliser toutes les colonnes de chaque ligne, vous utilisez des valeurs NULL dans les lignes où la colonne n'a pas de valeur. Je suggère également que vous inclure une ligne « type » de sorte que le client peut dire le type (et colonnes intéressantes) pour une ligne donnée.
Exemple:
(Select
'room' as view_type
, rooms.room as room
, NULL as color
From rooms
)
UNION ALL
(Select
'color' as view_type
, NULL as room
, colors.color as color
From colors
)
Vous voulez en fait une jointure croisée:
select v1.a, V1.B, VIEW3.z, v1.c de (SELECT a, b, c, à partir de View1, View2 où VIEW1.a = VIEW2.a) sous la forme v1 CROSS JOIN View3