Вопрос

Возможно ли ОБЪЕДИНИТЬ запросы из таблиц или представлений, которые не имеют никакого общего результата?То, что я пытаюсь сделать, это объединить данные из разных представлений в один результат.У меня есть

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, и представления не имеют первичных ключей.Большое спасибо.

Это было полезно?

Решение

Если я понимаю ваш вопрос, вы, вероятно, получаете подобные результаты:

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

Правильно ли я понимаю проблему?

Если это правильно, вам нужно будет найти способ объединить эти подзапросы вместе, чтобы вы могли сообщить SQL, что 1-е идут вместе, и 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

Но, и здесь есть большое "НО".Если у вас есть более одной строки в любом из представлений, в конечном итоге вы получите данные, которые не принадлежат друг другу.В таком случае, вы должен есть что-то общее.

Вот полный код, который я попробовал, вместе с результатами:

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, например:

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() сработал для меня.Подход 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

Может быть, вы ищете что-то подобное?(просто дикое предположение)

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, включая объединение, представляют собой статический набор столбцов.(Никакого полиморфизма.)

Но вам не обязательно использовать все столбцы в каждой строке, вы используете нулевые значения в строках, где столбец не имеет значения.Я также предлагаю вам включить строку "тип", чтобы клиент мог указать тип (и интересные столбцы) для данной строки.

Пример:

 (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) как v1 ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ ПРОСМОТР3

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top