SQL从3个表创建视图

时间:2018-07-18 13:39:28

标签: sql sql-server view

我有三个表:产品,属性和AttributesDefinitions。

产品: +----+------+ | Id | Name | +----+------+ | 1 | Shoe1| +----+------+ | 2 | Shoe2| +----+------+ | 3 | Shoe3| +----+------+

属性定义: +----+---------+ | Id | Name | +----+---------+ | 1 | Color | | 2 | Type | | 3 | Destiny | +----+---------+

属性:

+----+--------------+--------------+-----------+ | Id | Value | DefinitionId | ProductId | +----+--------------+--------------+-----------+ | 1 | Brown | 1 | 2 | | 2 | Yellow | 1 | 1 | | 3 | Sport | 3 | 1 | | 4 | Jelly shoes | 2 | 1 | | 5 | Normal shoes | 2 | 2 | +----+--------------+--------------+-----------+

在AttributesDefinitions中,我需要属性定义。

在“属性”中,我具有属性及其值。

每个产品都有许多属性,但是每种类型只有1个(属性定义)。

我的任务是创建一个包含产品列表及其所有属性值的视图。 它应该看起来像这样:

ProductsWithAttributesView:

+---------+--------+--------------+---------+ | Product | Color | Type | Destiny | +---------+--------+--------------+---------+ | Shoe1 | Yellow | Jelly shoes | Sport | | Shoe2 | Brown | Normal shoes | NULL | | Shoe3 | NULL | NULL | NULL | +---------+--------+--------------+---------+ 这样做的目的是获取B2B平台上的产品列表,并能够通过属性值对其进行过滤。

任何帮助我该如何实现?

2 个答案:

答案 0 :(得分:0)

正如我在评论中所述,我非常不同意您描述的架构,因为在我看来,Products表应该与Attributes具有一对多或多对多关系。换句话说,一个产品可以具有许多属性,并且许多产品可以共享相同的属性。此外,由于您提到的设计和最终目标是什么(一个具有任意长度的属性列表作为列的产品),您可能无法提出要求。您可以通过在View定义中精心设计的PIVOT语句来实现这些结果。首先让我知道下面的代码是否有效。

话虽如此,如果我假设您正在使用T-SQL,那么此代码将创建您描述的表,并基于对表执行JOIN来创建View。希望这可以将您推向正确的方向以继续前进。

CREATE TABLE Products
(
Id INT PRIMARY KEY,
Name VARCHAR(255)
);

CREATE TABLE AttributesDefinition
(
Id INT PRIMARY KEY,
Name VARCHAR(255)
);

CREATE TABLE Attributes
(
Id INT,
Name VARCHAR(255),
Value VARCHAR(255),
DefinitionId INT FOREIGN KEY REFERENCES AttributesDefinition (Id),
ProductId INT FOREIGN KEY REFERENCES Products (Id)
);


CREATE VIEW ProductsWithAttributesView AS
SELECT p.Name AS Products
,ad.Name AS AttributeDefinition
,a.Name AS AttributeName
,a.Value AS AttributeValue
FROM Products p 
INNER JOIN Attributes a ON p.Id = a.ProductId
INNER JOIN AttributesDefinition ad ON ad.Id = a.DefinitionId;

SELECT * FROM ProductsWithAttributesView;

答案 1 :(得分:0)

我使用CaitLAN Jenner的代码来介绍我的解决方案,但是我不确定是否可以创建添加新类别后可以动态适应的视图。

CREATE TABLE Products
(
Id INT PRIMARY KEY,
Name VARCHAR(255)
);

INSERT INTO Products (Id,Name)
VALUES (1,'Car'),(2,'Motorcycle'),(3,'Bicycle')

CREATE TABLE AttributesDefinition
(
Id INT PRIMARY KEY,
Name VARCHAR(255)
);

INSERT INTO AttributesDefinition (Id,Name)
VALUES (1,'Number of wheels'),(2,'People'),(3,'Engine')

CREATE TABLE Attributes
(
Id INT,
Name VARCHAR(255),
Value VARCHAR(255),
DefinitionId INT FOREIGN KEY REFERENCES AttributesDefinition (Id),
ProductId INT FOREIGN KEY REFERENCES Products (Id)
);

INSERT INTO Attributes (Id, Name, Value, DefinitionId, ProductId)
VALUES (1,'Number of wheels','4',1,1),
 (2,'Number of wheels','2',1,2),
 (3,'Number of wheels','2',1,3),
 (4,'People','4',2,1),
 (5,'People','2',2,2),
 (6,'People','1',2,3),
 (7,'Engine','V6',3,1),
 (8,'Engine','V2',3,2)


CREATE VIEW ProductsWithAttributesView AS
SELECT      
    products.Name as 'Products',
    atr1.Value As 'Number of wheels',
    atr2.Value As 'People',
    atr3.Value As 'Engine'
FROM Products AS products
LEFT JOIN Attributes AS atr1 ON atr1.ProductId = products.Id AND atr1.DefinitionId = 1
LEFT JOIN Attributes AS atr2 ON atr2.ProductId = products.Id AND atr2.DefinitionId = 2
LEFT JOIN Attributes AS atr3 ON atr3.ProductId = products.Id AND atr3.DefinitionId = 3

结果

Products  | Number of wheels |  People | Engine
Car       |  4               |   4     | V6
Motorcycle|  2               |   2     | V2
Bicycle   |  2               |   1     | NULL

编辑。这与枢轴:

CREATE VIEW ProductsWithAttributesView2 AS
WITH pivot_data AS
(
SELECT products.Name as Products, -- Grouping Column
def.Name as AtrName, -- Spreading Column
Value -- Aggregate Column
FROM Attributes atr
INNER JOIN Products products ON atr.ProductId = products.Id 
INNER JOIN AttributesDefinition def ON def.Id = atr.DefinitionId 
)
SELECT Products, [Number of wheels],[People],[Engine]
FROM pivot_data
PIVOT (max(value) FOR AtrName IN ([Number of wheels],[People],[Engine])) AS p;