我有一个名为Student
的表,其记录如下。
StudentId int PK NOT Null,
Name Varchar(50),
Age int,
DateofBirth Datetime and
ClassRecordID int NOT NULL
MajorID int NOT NULL
数据看起来像这样:
StudentID Name Age Dateofbirth ClassRecordID MajorID
1234 Sam 21 1/10/1991 1122 1
1235 NULL Null 1/12/1990 1123 2
1236 George Null NULL 1125 2
1237 Fanny NULL NULL 1155 1
我的要求是,
每当用户提供columnName
和MajorID
时,查询应从表中返回classRecordID
,其中指定的columnName
具有空值或空值。
例如,
当用户提供columnName = 'Age'
和MajorId = 2
时,查询应返回1123和1125.
同样,当用户提供columnName = 'Dateofbirth'
和MajorId = 2
时,查询应返回1125.
我尝试使用以下查询
Declare @ColumnName nvarchar(50)
Delcare @MajorId int
set @ColumnName = 'age' --for example
set @MajorId = 2 -- For example
SELECT DISTINCT TOP 10
ClassRecordID
FROM
dbo.Student WITH (NOLOCK)
WHERE
(@ColumnName IS NULL
OR LEN(LTRIM(RTRIM(@ColumnName))) = 0)
AND
MajorId = @MajorId
但它返回空而不是预期的结果。这个查询有什么问题?有没有更好的方法来做到这一点?我不想使用IF else方法。
答案 0 :(得分:2)
如果您真的希望能够按任意列进行过滤而无需在每次添加新列时扩展代码,则可以使用动态SQL和sp_executesql
。此代码段应该适合您:
declare @nullFilterColumnName varchar(50)
set @nullFilterColumnName = 'Age'
declare @majorId int
set @majorId = 2
declare @sql nvarchar(max)
set @sql = 'select distinct ClassRecordID from Students where isnull('
+ quotename(@nullFilterColumnName)
+ ', '''') = '''' and MajorId = '
+ cast(@majorId as nvarchar(20))
exec sp_executesql @sql
但我建议使用此选项作为最后的手段。 @ron tornambe的版本更强大。
答案 1 :(得分:1)
我认为这种技巧是你所寻求的:
SELECT DISTINCT TOP 10
ClassRecordID
FROM
dbo.Student WITH (NOLOCK)
WHERE
1 = CASE WHEN @ColumnName = 'Age' THEN
CASE WHEN Age IS NULL THEN 1 ELSE 0 END
ELSE CASE WHEN @ColumnName = 'DateofBirth' THEN
CASE WHEN DateOfBirth IS NULL THEN 1 ELSE 0 END
END
AND MajorId = @MajorId