我遇到了一个问题,在代码中无需进行大量更改,我似乎无法解决这个问题,而且我认为必须有一个我根本不了解的更简单的解决方案。
我有一张产品名称,产品位置和各种状态(从1到10)的表格。我具有所有产品和位置的数据,但只有一些状态(例如,城市XX中的产品X具有类别1和3的数据,城市YY中的产品Y具有类别1至6的数据)。
我想始终显示每个产品/位置的10次重复,以及相应的数据(如果有)或null。这使我计划创建的报告更易于阅读和理解。
我正在SQL Server 2016上使用SSMS2017。
SELECT
[Product],
[Location],
[Category],
[Week1],
[Week2],
[Week3]
FROM MyView
自然,它只会返回我拥有的数据,但我想始终为每种产品/位置组合返回所有10行(如果我那里没有数据,则在Week列中为null)。
答案 0 :(得分:3)
您的问题主义者还不太清楚,但是我认为我神奇的水晶球给了我一个很好的猜测:
我认为您正在寻找LEFT JOIN
和CROSS JOIN
:
-下次请自己创建一个独立示例
-我用样本数据创建了3个哑表
DECLARE @tblStatus TABLE(ID INT IDENTITY,StatusName VARCHAR(100));
INSERT INTO @tblStatus VALUES('Status 1')
,('Status 2')
,('Status 3')
,('Status 4')
,('Status 5');
DECLARE @tblGroup TABLE(ID INT IDENTITY,GroupName VARCHAR(100));
INSERT INTO @tblGroup VALUES ('Group 1')
,('Group 2')
,('Group 3')
,('Group 4')
,('Group 5');
DECLARE @tblProduct TABLE(ID INT IDENTITY,ProductName VARCHAR(100),StatusID INT, GroupID INT);
INSERT INTO @tblProduct VALUES ('Product 1, Status 1, Group 2',1,2)
,('Product 2, Status 1, Group 3',1,3)
,('Product 3, Status 3, Group 4',3,4)
,('Product 4, Status 3, Group 3',3,3)
,('Product 5, Status 1, Group 5',1,5);
-这将返回每个状态(与产品值无关)以及产品(如果有对应的行)
SELECT s.StatusName
,p.*
FROM @tblStatus s
LEFT JOIN @tblProduct p ON s.ID=p.StatusID
-这将首先使用CROSS JOIN
来创建每一个笛卡尔积。
-LEFT JOIN
的工作如上所述
SELECT s.StatusName
,g.GroupName
,p.*
FROM @tblStatus s
CROSS JOIN @tblGroup g
LEFT JOIN @tblProduct p ON s.ID=p.StatusID AND g.ID=p.GroupID;
如果这不是您所需要的,请尝试设置一个像我的示例并提供预期的输出。