我有一个名为“Students”的表格,其中包含......
等字段Student Code1 Code2 Code3 Code4
Mark 0 1 1 1 1
Joseph 0 1 0 1 0
Bryan. 0 0 1 1 1
因此,SQL查询应该选择具有大于或等于2的1的学生,并且它们也应该是连续的... 在上述情况下..应该返回Mark和Bryan而不是Joseph
答案 0 :(得分:0)
如果只有少数几列:
Select *
From Students
Where ( Code1 + Code2 ) = 2
Or ( Code2 + Code3 ) = 2
Or ( Code3 + Code4 ) = 2
Or ( Code4 + Code5 ) = 2
另一种解决方案:
With NormalizedData As
(
Select Student, Code1, 1 As Sequence From Students Where Code1 = 1
Union All Select Student, Code2, 2 From Students Where Code2 = 1
Union All Select Student, Code3, 3 From Students Where Code3 = 1
Union All Select Student, Code4, 4 From Students Where Code4 = 1
Union All Select Student, Code5, 5 From Students Where Code5 = 1
)
Select ...
From Students As S
Where Exists (
Select 1
From NormalizedData As N1
Join NormalizedData As N2
On N2.Student = N1.Student
And N2.Sequence = N1.Sequence + 1
Where N1.Student = S.Student
)
答案 1 :(得分:0)
虽然你的架构是非常非常奇怪的,但你可以使用UNPIVOT来解决它,假设你使用的是SQL Server 2005或更高版本。请注意,您必须向unpivot提供所有代码的硬编码列表...
WITH pvt (student, code, value) as (
SELECT
Student,
ROW_NUMBER()OVER(Partition By Student Order By Codes) as CodeId,
Value
FROM
( select * from students ) P
UNPIVOT (
Value FOR Codes IN (Code1, Code2, Code3, Code4, Code5)
) Code
)
select
distinct
pvt.student
from
pvt
inner join pvt p2
on p2.code = pvt.code + 1
and p2.student = pvt.student
where
pvt.value = 1 and p2.value = 1
这里真正的优点是你只需要在一个地方处理你的各种代码 - 例如,如果你添加Code6,你只需将它添加到UNPIVOT中,它就会被合并到代码中。
另请注意,这只是解决了“学生必须在代码中连续2个1”的更一般要求。它不会检查学生有多少1,或者关心2值下降的位置。
最后一点需要注意的是,ROW_NUMBER()函数假设您的代码按顺序命名,没有间隙,因此如果从Code7转到Code9,它只会假设这两个代码是“连续的”。