我有一个查询,它在定义的日期范围(最近10年)中提取列中的值。如果某一特定日期缺少该列中的数据,则该行根本不存在于表中。
有没有办法可以在没有行的情况下返回NULL?基本上,我仍然希望返回范围内的所有日期,但如果行不存在,那么我将只返回该特定日期的NULL。
发布于 2021-09-13 14:44:10
下面列出了两个日期之间的所有日期。
DECLARE @MinDate DATE = '20110913',
@MaxDate DATE = '20210913';
SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1,
@MinDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;使用此表按日期联接到您的表,缺少的任何日期都将显示为null。
发布于 2021-09-13 15:18:49
您只需要左连接,在下面的示例中,即使用户没有订单,也会显示用户。左连接意味着即使在右表中没有匹配的数据,也要将数据保留在左侧,如果使用内部连接,那么它将只返回在两个表中都有数据的行,因此将删除空的OrderId行。
我注意到你也提到了日期范围(例如,日期表),这可能是第二部分,所以如果你沿着这条路线走,这可能会有所帮助,https://www.brentozar.com/archive/2020/08/date-tables-are-great-for-users-but-not-so-great-for-performance/

查看下面的完整示例您可以运行,请注意左连接
BEGIN TRANSACTION
BEGIN TRY
CREATE TABLE #Users (
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL
)
INSERT INTO #Users ([Name] )
VALUES('Andrew'),
('Bob'),
('Dave'),
('Philip')
SELECT * FROM #Users
CREATE TABLE #Orders (
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
UserId INT NOT NULL,
Cost DECIMAL(18,2) NOT NULL,
CONSTRAINT FK_Orders_Users FOREIGN KEY (UserId) REFERENCES #Users (Id)
)
INSERT INTO #Orders (UserId, Cost)
VALUES(1, 2.99),
(1, 5.99),
(4, 8.99)
SELECT * FROM #Orders
SELECT U.Id AS UserId, U.[Name], O.Id AS OrderId FROM #Users AS U
LEFT JOIN #Orders AS O ON O.UserId = U.Id
ROLLBACK TRANSACTION
END TRY
BEGIN CATCH
PRINT 'Rolling back changes, there was an error!!'
ROLLBACK TRANSACTION
DECLARE @Msg NVARCHAR(MAX)
SELECT @Msg=ERROR_MESSAGE()
RAISERROR('Error Occured: %s', 20, 101,@msg) WITH LOG
END CATCHhttps://stackoverflow.com/questions/69164526
复制相似问题