联合列在SQL中垂直

时间:2012-12-10 12:59:03

标签: sql sql-server sql-server-2008 tsql

假设这些表:

群组 :(身份证,标题):{1,G1}, {2,G2}, {3,G3}, {4, G4}

类别 :( Id,标题):{1, Cat1}, {2, Cat2}, {3, Cat3}, {4, Cat4}

产品 :( Id,GroupId,CategoryId,Name):

{1, 1, 1, G1C1P1},
{2, 1, 2, G1C2P2},
{3, 1, 2, G1C2P3},
{4, 2, 2, G2C2P4},
{5, 2, 2, G2C2P5},
{6, 3, 1, G3C1P6},
{7, 3, 3, G3C3P7}

经销商 :(身份证,姓名):{1, 'Dealer1'}, {2, 'Dealer2'}, {3, 'Dealer3'}

ProductDealer (Id,ProductId(UK),DealerId,LastSale,Number):

{1, 1, 1, 5, '2012-12-10 12:34:31'}, 
{2, 2, 2, 120, '2012-11-10 12:34:31'}, 
{3, 5, 1, 75, '2012-12-02 12:34:31'}

所以我要创建一个完整的产品视图,这是我的第一次尝试:

SELECT 
    [PR].[Id],
    [PR].[Name],
    [PR].[GroupId],
    [GR].[Title] AS [Group],
    [PR].[CategoryId],
    [CA].[Title] AS [Category]

FROM [dbo].[Product] AS [PR]
INNER JOIN [dbo].[Group] AS [GR] ON [PR].[GroupId] = [GR].[Id]
INNER JOIN [dbo].[Category] AS [CA] ON [PR].[CategoryId] = [CA].[Id]

然后我想添加ProductDealer列进行查看,所以我试试这个:

SELECT 
    [PR].[Id],
    [PR].[Name],
    [PR].[GroupId],
    [GR].[Title] AS [Group],
    [PR].[CategoryId],
    [CA].[Title] AS [Category],
    ISNULL(
    (SELECT [PD].[Id] FROM [dbo].[ProductDealer] AS [PD] 
     WHERE [PD].[ProductId] = [PR].[Id]),
     CAST(-1 AS BIGINT)
    ) AS [ProductDealerId],
    ISNULL(
    (SELECT [DE].[Id] FROM [dbo].[Dealer] AS [DE]
    INNER JOIN [dbo].[ProductDealer] AS [PD] ON [DE].[Id] = [PD].[DealerId]
     WHERE [PD].[ProductId] = [PR].[Id]),
     CAST(-1 AS BIGINT)
    ) AS [DealerId],
     ISNULL(
    (SELECT [DE].[Name] FROM [dbo].[Dealer] AS [DE]
    INNER JOIN [dbo].[ProductDealer] AS [PD] ON [DE].[Id] = [PD].[DealerId]
     WHERE [PD].[ProductId] = [PR].[Id]),
     CAST('HaveNotDealer' AS NVARCHAR)
    ) AS [Dealer],
    ISNULL(
    (SELECT [PD].[LastSale] FROM [dbo].[ProductDealer] AS [PD] 
     WHERE [PD].[ProductId] = [PR].[Id]),
    CAST('0001-01-01 00:00:01' AS DATETIME2)
    ) AS [LastSale],
    ISNULL(
    (SELECT [PD].[Number] FROM [dbo].[ProductDealer] AS [PD] 
     WHERE [PD].[ProductId] = [PR].[Id]),
    CAST(0 AS BIGINT)
    ) AS [SaleNumber]

FROM [dbo].[Product] AS [PR]
INNER JOIN [dbo].[Group] AS [GR] ON [PR].[GroupId] = [GR].[Id]
INNER JOIN [dbo].[Category] AS [CA] ON [PR].[CategoryId] = [CA].[Id]

正如您在ProductDealer中看到的每一列,我写了一个完整的选择查询,我不知道有没有更好的方法来做到这一点?比如将这些列合并到第一个视图,你有什么建议来最好地实现它?

更新

ProductDealer表中,ProductId是英国,所以每个产品都可以有一个经销商或者没有,我想如果产品有经销商获得ProductDealer列,如果没有得到我的默认值,如:( - 1,'HaveNotDealer')。

4 个答案:

答案 0 :(得分:3)

SELECT 
    [PR].[Id],
    [PR].[Name],
    [PR].[GroupId],
    [GR].[Title] AS [Group],
    [PR].[CategoryId],
    [CA].[Title] AS [Category],
    ISNULL([PD].[Id],
    CAST(-1 AS BIGINT)) AS [ProductDealerId],
    ISNULL([D].Id,
    CAST(-1 AS BIGINT)) as DealerId,
    ISNULL([D].Name,
    CAST('HaveNotDealer' AS NVARCHAR)) as DealerName,
    ISNULL(PD.LastSale,
    CAST('0001-01-01 00:00:01' AS DATETIME2)) as LastSale,
    ISNULL([PD].Number,
    CAST(0 AS BIGINT)) as SaleNumber

FROM [dbo].[Product] AS [PR]
INNER JOIN [dbo].[Group] AS [GR] ON [PR].[GroupId] = [GR].[Id]
INNER JOIN [dbo].[Category] AS [CA] ON [PR].[CategoryId] = [CA].[Id]
LEFT OUTER JOIN [dbo].[ProductDealer] AS [PD] ON [PR].[Id] = [PD].[ProductId]
LEFT OUTER JOIN [dbo].[Dealer] AS [D] ON [PD].DealerId = [D].Id

答案 1 :(得分:1)

这是“垂直UNION”版本:

WITH "Group"
     AS
     (
      SELECT * 
        FROM (
              VALUES (1,'G1'), (2,'G2'), (3,'G3'), (4, 'G4')
             ) AS T (Id, Title)
     ),
     Category
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 'Cat1'), (2, 'Cat2'), (3, 'Cat3'), (4, 'Cat4')
             ) AS T (Id, Title)
     ),
     Product
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 1, 1, 'G1C1P1'),
                     (2, 1, 2, 'G1C2P2'),
                     (3, 1, 2, 'G1C2P3'),
                     (4, 2, 2, 'G2C2P4'),
                     (5, 2, 2, 'G2C2P5'),
                     (6, 3, 1, 'G3C1P6'),
                     (7, 3, 3, 'G3C3P7')
             ) AS T (Id, GroupId, CategoryId, Name)
     ),
     Dealer
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 'Dealer1'), (2, 'Dealer2'), (3, 'Dealer3')
             ) AS T (Id, Name)
     ),
     ProductDealer 
     AS
     (
      SELECT *
        FROM (
              VALUES (1, 1, 1, 5, '2012-12-10 12:34:31'), 
                     (2, 2, 2, 120, '2012-11-10 12:34:31'), 
                     (3, 5, 1, 75, '2012-12-02 12:34:31')
             ) AS T (Id, ProductId, DealerId, Number, LastSale)
     )     
SELECT PR.Id, PR.Name, PR.GroupId, GR.Title AS "Group",
       PR.CategoryId, CA.Title AS Category, 
       PD.Id AS ProductDealerId,
       D.Id DealerId,
       D.Name AS DealerName,
       PD.LastSale AS LastSale,
       PD.Number AS SaleNumber
  FROM Product AS PR
       JOIN "Group" AS GR ON PR.GroupId = GR.Id
       JOIN Category AS CA ON PR.CategoryId = CA.Id
       JOIN ProductDealer AS PD ON PR.Id = PD.ProductId
       JOIN Dealer AS D ON PD.DealerId = D.Id

UNION

SELECT PR.Id, PR.Name, PR.GroupId, GR.Title AS "Group",
       PR.CategoryId, CA.Title AS Category, 
       PD.Id AS ProductDealerId,
       CAST(-1 AS BIGINT) DealerId,
       CAST('HaveNotDealer' AS NVARCHAR) AS DealerName,
       PD.LastSale AS LastSale,
       PD.Number AS SaleNumber
  FROM Product AS PR
       JOIN "Group" AS GR ON PR.GroupId = GR.Id
       JOIN Category AS CA ON PR.CategoryId = CA.Id
       JOIN ProductDealer AS PD ON PR.Id = PD.ProductId
 WHERE PD.DealerId NOT IN ( SELECT Id FROM Dealer )

UNION

SELECT PR.Id, PR.Name, PR.GroupId, GR.Title AS "Group",
       PR.CategoryId, CA.Title AS Category, 
       CAST(-1 AS BIGINT) AS ProductDealerId,
       CAST(-1 AS BIGINT) DealerId,
       CAST('HaveNotDealer' AS NVARCHAR) AS DealerName,
       CAST('0001-01-01 00:00:01' AS DATETIME2) AS LastSale,
       CAST(0 AS BIGINT) AS SaleNumber
  FROM Product AS PR
       JOIN "Group" AS GR ON PR.GroupId = GR.Id
       JOIN Category AS CA ON PR.CategoryId = CA.Id
 WHERE PR.Id NOT IN ( SELECT ProductId FROM ProductDealer );

答案 2 :(得分:0)

像这样:

SELECT 
    [PR].[Id],
    [PR].[Name],
    [PR].[GroupId],
    [GR].[Title] AS [Group],
    [PR].[CategoryId],
    [CA].[Title] AS [Category],
    PD.ID AS ProductDealerID,
    PD.DealerId,
    DE.Name AS Dealer,
    PD.LastSale,
    PD.Number AS SaleNumber

FROM [dbo].[Product] AS [PR]
INNER JOIN [dbo].[Group] AS [GR] ON [PR].[GroupId] = [GR].[Id]
INNER JOIN [dbo].[Category] AS [CA] ON [PR].[CategoryId] = [CA].[Id]
LEFT JOIN  ProductDealer AS [PD] ON PD.ProductId = PR.ID
LEFT JOIN  Dealer AS DE ON DE.ID = PD.DealerId

答案 3 :(得分:0)

也许只是在“精神”中回答了这个问题,但这是我偶然发现此问题时正在寻找的“垂直联合列”答案)

with aa(col1, col2) as (
    select * from (values (1,2) ) blah
),
 bb(col3, col4) as (
    select * from (values (5,6) ) blah
)

select select aa.col1, aa.col2, bb.col3, bb.col4
from aa , bb

给予

col1|col2|col3|col4
1   |2   |5   |6   

免责声明:以上内容仅适用于aabb单行。