SQL中的垂直联合列
假设以下表格: 组:(Id,标题):SQL中的垂直联合列,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,假设以下表格: 组:(Id,标题):{1,G1},{2,G2},{3,G3},{4,G4} 类别:(Id,标题):{1,Cat1},{2,Cat2},{3,Cat3},{4,Cat4} 产品:(Id、GroupId、CategoryId、名称): 经销商:(Id,名称):{1,'Dealer1'},{2,'Dealer2'},{3,'Dealer3'} 产品经销商(Id、产品Id(英国)、经销商Id、上次销售、编号): 因此,我将创建产品的完整视图,这是我的第一次尝试: SELECT
{1,G1},{2,G2},{3,G3},{4,G4}
类别:(Id,标题):{1,Cat1},{2,Cat2},{3,Cat3},{4,Cat4}
产品:(Id、GroupId、CategoryId、名称):
经销商:(Id,名称):{1,'Dealer1'},{2,'Dealer2'},{3,'Dealer3'}
产品经销商(Id、产品Id(英国)、经销商Id、上次销售、编号):
因此,我将创建产品的完整视图,这是我的第一次尝试:
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
中看到的那样,我编写了一个完整的select查询,我不知道有没有更好的方法来实现这一点?类似于将此列与first view合并,您建议如何最好地实现它
更新
在ProductDealer
表中,ProductId
是UK,因此每个产品可能有一个经销商或没有经销商,如果产品有经销商,我想查看ProductDealer
列,如果没有,则获取默认值,如:(-1,'HaveNotDealer')。如下:
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
像这样:
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
以下是“垂直联合”版本:
以下是“垂直联合”版本:
也许只是用“精神”来回答这个问题,但这就是我偶然发现这个问题时所寻找的“联合专栏”答案=) 给予
免责声明以上仅适用于单行
aa
,bb
,也许只是用“精神”来回答这个问题,但这是我偶然发现这个问题时寻找的“垂直联合列”答案=)
给予
免责声明以上仅适用于单行
aa
,bb
您需要更清楚地了解您想要实现的目标。对于每种产品,您是否希望将该产品的每个经销商的详细信息附加到末尾列和销售数量(或其他摘要)?或者你想要像[产品栏][第一个经销商栏][第二个经销商栏][…]这样的东西吗?如果是这样的话,我建议最好在你的展示层做一些事情,如果可能的话。@Ian Yates inProductDealer
TableProductId
是英国的,因此每个产品可能有一个经销商,或者没有经销商,我希望如果产品的“经销商获取”ProductDealer
列在视图中,如果没有,则获取我的默认值,如:(-1,“HaveNotDealer”),您需要更清楚地了解您要实现的目标。对于每种产品,您是否希望将该产品的每个经销商的详细信息附加到末尾列和销售数量(或其他摘要)?或者你想要像[产品栏][第一个经销商栏][第二个经销商栏][…]这样的东西吗?如果是这样的话,我建议最好在你的展示层做一些事情,如果可能的话。@Ian Yates inProductDealer
TableProductId
是英国的,因此每个产品可能有一个经销商,或者没有经销商,我想要查看产品中是否有经销商获取ProductDealer
列,如果没有,则获取默认值,如:(-1,'HaveNotDealer')
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
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
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 );
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