1

共通の結果を持たないテーブルまたはビューからクエリを UNION することは可能ですか? 私がやろうとしているのは、さまざまなビューからのデータを 1 つの結果に結合することです。私は持っている

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 ? 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 を使用していますが、ビューには主キーがありません。本当にありがとう。

4

7 に答える 7

2

あなたの質問を理解できれば、おそらく次のような結果が得られるでしょう。

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

..しかし、取得しようとしているのは、次のような結果です。

a1, b1, z1, c1
a2, b2, z2, c2
a3, b2, z3, c3

問題を正しく理解していますか?

これが正しければ、これらのサブクエリを結合する方法が必要です。これにより、1 が一緒になり、2 が一緒になる、というように SQL に伝えることができます。

于 2009-05-19T21:08:01.917 に答える
2

ユニオンは結果セットを連結しますが、結合はしません。

したがって、最初のクエリから得られるものは次のとおりです。

  a      b    (null)  c
(null) (null)   z    (null)

それらを結合したい場合は、それらを結合する必要があり、次に共通点が必要になるか、プログラム内のデータを結合する必要があります。

それぞれから1行しかありませんか?

その場合、上記のパターンが常にそのようになる場合、これは機能します。

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

しかし、ここには大きな BUT があります。いずれかのビューに複数の行がある場合、一緒に属さないデータになってしまいます。その場合、共通点がなければなりません。

結果とともに、私が試した完全なコードは次のとおりです。

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)

次のように、View3 に 1 つの行を追加するとします。

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)
于 2009-05-19T21:08:17.423 に答える
1


複数のレコードの場合、ROW_NUMBER() アプローチがうまくいきました。Select 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
于 2016-10-08T18:38:43.377 に答える
1

私がこれを理解していれば、結果を「折りたたんで」すべての NULL を取り除こうとしていますか? もしそうなら、view3 からの結果は view1/view2 からの結果に対応しますか? もしそうなら、その関係は何ですか?そうでない場合、結果の数は少なくとも一致しますか?

于 2009-05-19T21:05:40.283 に答える
0

ユニオンを含む任意の SQL 選択の結果は、列の静的セットです。(ポリモーフィズムはありません。)

ただし、各行のすべての列を使用する必要はありません。列に値がない行には null 値を使用します。また、クライアントが特定の行のタイプ (および興味深い列) を判断できるように、「タイプ」行を含めることをお勧めします。

例:

 (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 
)
于 2009-05-19T21:11:17.057 に答える
0

このようなものを探しているということはありますか?(ただの勝手な推測)

SELECT 
  VIEW1.a,
  VIEW1.b,
  (SELECT TOP 1 z FROM VIEW3) AS z,
  VIEW2.c
FROM
  VIEW1, VIEW2 
WHERE
  VIEW1.a = VIEW2.a
于 2009-05-19T21:07:04.430 に答える
0

実際にはクロス結合が必要です。

select v1.a,v1.b,VIEW3.z,v1.c from (SELECT a,b,c, FROM VIEW1, VIEW2 where VIEW1.a = VIEW2.a) as v1 CROSS JOIN VIEW3

于 2009-05-19T21:22:06.973 に答える