نتائج الاتحاد يختار في SQL Server
-
23-08-2019 - |
سؤال
هل من الممكن استفسارات النقابات من الجداول أو وجهات النظر التي لا تملك أي نتيجة مشتركة؟ ما أحاول القيام به هو الجمع بين البيانات من وجهات النظر المختلفة إلى نتيجة واحدة. لدي
select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3
أود أن يكون النتيجة A، B، Z، C. هل هذا حيث كنت أستخدمها. كيف يبدو ذلك؟
select ? from (
select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3)
أنا أستخدم MS SQL Server والمناظر لا تحتوي على مفاتيح أساسية. شكرا جزيلا.
المحلول
إذا فهمت سؤالك، فربما تحصل على نتائج مثل هذا:
a1, b1, null, c1
a2, b2, null, c2
a3, b2, null, c3
null, null, z1, null
null, null, z2, null
null, null, z3, nul
ل
.. ولكن ما تحاول الحصول عليه هو النتائج مثل هذا:
a1, b1, z1, c1
a2, b2, z2, c2
a3, b2, z3, c3
هل أفهم المشكلة بشكل صحيح؟
إذا كان هذا صحيحا، فستحتاج إلى الحصول على وسيلة للانضمام إلى هذه النظارات المنقذة معا، بحيث يمكنك أن تخبر SQL أن تسير المجموعة الأولى، وتذهب 2 إلى الأمام، وهلم جرا.
نصائح أخرى
يتسلسل النقابة مجموعات النتائج، فهي لا تجمعها.
إذن ما سوف تحصل عليه من الاستعلام الأول الخاص بك هو:
a b (null) c
(null) (null) z (null)
إذا كنت ترغب في الجمع بينها، فسيتعين عليك الانضمام إليها، ثم تحتاج إلى شيء مشترك، أو عليك الجمع بين البيانات الواردة في البرنامج.
هل لديك فقط صف واحد من كل؟
إذا كان الأمر كذلك، فما إذا كان النمط أعلاه سيكون دائما هكذا، فامنح ذلك:
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
ومع ذلك، إذا كنت لا تعرف ما إذا كان View3.a لديه قيمة أو View1.a لديه قيمة، وتريد واحد من الاستعلام الأول إذا كانت هناك قيمة 3، فامنح هذا:
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
ولكن، وهناك كبير ولكن هنا. إذا كان لديك أكثر من صف واحد في أي من الآراء، فسوف ينتهي بك الأمر مع البيانات التي لا تنتمي معا. في هذه الحالة، أنت يجب لديهم شيء مشترك.
إليك الكود الكامل الذي حاولت فيه، مع النتائج:
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
نتائج:
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)
إذا قمت بإضافة صف واحد واحد لعرض 3، مثل هذا:
INSERT INTO View3 (z) VALUES (51)
ثم ستحصل على هذه النتائج، لاحظ الصفوف المضاعفة:
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)
إذا فهمت هذا: هل تحاول "انهيار" نتائجك والتخلص من كل الخبز؟ إذا كان الأمر كذلك، فستنتج من أي وقت مضى من View3 تتوافق مع النتيجة من View1 / View2؟ إذا كان الأمر كذلك، فما هي العلاقة؟ إذا لم يكن الأمر كذلك، فقم بعدد النتائج على الأقل تطابق؟
لعدة سجلات، عملت نهج ROW_NUMBER () بالنسبة لي. وكانت نهج الاختيار 1 K يعود إلى المنتج الديكارتية.
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
هل يمكن أن يكون ذلك تبحث عن شيء مثل هذا؟ (مجرد تخمين البرية)
SELECT
VIEW1.a,
VIEW1.b,
(SELECT TOP 1 z FROM VIEW3) AS z,
VIEW2.c
FROM
VIEW1, VIEW2
WHERE
VIEW1.a = VIEW2.a
النتائج من أي SQL حدد، بما في ذلك الاتحاد، هي مجموعة ثابتة من الأعمدة. (لا تعدد الأشكال.)
ولكن ليس عليك استخدام جميع الأعمدة في كل صف، يمكنك استخدام القيم الخالية في الصفوف حيث لا يحتوي العمود على قيمة. أقترح أيضا أن تتضمن صف "نوع" حتى يمكن للعميل أن يخبر النوع (وأعمدة مثيرة للاهتمام) صف معين.
مثال:
(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
)
تريد فعلا عبور تنضم:
حدد v1.a، v1.b، view3.z، v1.c من (حدد A، B، C، من View1، View2 حيث View1.a = View2.a) as v1 cross انضم View3