Pergunta

É possível consultas união de tabelas ou exibições que não têm qualquer resultado em comum? O que eu estou tentando fazer é combinar dados de diferentes pontos de vista em um resultado. Tenho

select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3

Eu gostaria que o resultado seja a, b, z, c. É aqui que eu usaria selecione a partir de? O que isso parece?

select ? from (
select a,b,null,c from VIEW1, VIEW2 where VIEW1.a = VIEW2.a
UNION
select null,null,z,null from VIEW3)

Estou usando o MS SQL Server e as vistas não têm chaves primárias. Muito obrigado.

Foi útil?

Solução

Se entendi sua pergunta, você provavelmente está obtendo resultados como este:

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

.. mas o que você está tentando fazer com que são resultados como este:

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

Do I compreender o problema corretamente?

Se isto estiver correto, você precisa ter uma maneira de juntar esses subconsultas em conjunto, de modo que você pode dizer SQL que os 1s andam juntos, e os 2 lá juntos, e assim por diante.

Outras dicas

concatena sindicais resultado conjuntos, não combiná-los.

Então, o que você vai começar a partir de sua primeira consulta é a seguinte:

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

Se você quiser combiná-los, você vai ter que se juntar a eles, e então você precisa ter algo em comum, ou você vai ter que combinar os dados no programa.

Você só tem 1 linha de cada um?

Se sim, então se o padrão acima é sempre vai ser assim, isso iria funcionar:

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

No entanto, se você não sabe se View3.a tem um valor ou View1.a tem um valor, e você quer a partir da primeira consulta se houver um valor de 3, então isso iria funcionar:

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

Mas, e há um grande MAS aqui. Se você tem mais de uma linha em qualquer uma das vistas, você vai acabar com dados que não pertence juntos. Nesse caso, você deve tem algo em comum.

Aqui está o código completo que eu tentei, juntamente com os resultados:

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

Resultado:

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)

Se você adicionar uma única linha para View3, como este:

INSERT INTO View3 (z) VALUES (51)

Em seguida, você poderá obter estes resultados, observe as linhas duplas:

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)

Se eu entender isso: você está tentando 'colapso' seus resultados e se livrar de todos os nulos? Se assim for, nunca vai resultar de view3 correspondem a um resultado de view1 / view2? Se sim, qual é a relação? Se não, o número de resultados pelo menos igualar?


para vários registros, abordagem ROW_NUMBER () funcionou para mim. A abordagem k Select 1 foi devolver um produto cartesiano.

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

Pode ser que você está procurando algo parecido com isto? (Apenas um palpite)

SELECT 
  VIEW1.a,
  VIEW1.b,
  (SELECT TOP 1 z FROM VIEW3) AS z,
  VIEW2.c
FROM
  VIEW1, VIEW2 
WHERE
  VIEW1.a = VIEW2.a

Os resultados de qualquer SQL SELECT, incluindo uma união, é um conjunto estático de colunas. (Nenhum polimorfismo.)

Mas você não tem que usar todas as colunas em cada linha, você usa valores nulos nas linhas onde a coluna não tem um valor. Sugiro também que você incluir uma linha 'tipo' para que o cliente pode dizer o tipo (e colunas interessantes) para uma determinada linha.

Exemplo:

 (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 
)

Você realmente quer uma junção cruzada:

select v1.a, v1.b, VIEW3.z, v1.c de (SELECT a, b, c, A PARTIR DE view1, view2 onde VIEW1.a = VIEW2.a) como v1 CROSS JOIN VIEW3

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top