我遇到了一个场景,我会用一些虚拟数据来解释它。见下表
Select * from LUEmployee
empId name joiningDate
1049 Jithin 3/9/2009
1017 Surya 1/2/2008
1089 Bineesh 8/24/2009
1090 Bless 7/15/2009
1014 Dennis 1/5/2008
1086 Sus 9/10/2009
只有当月份是一月、三月、七月或十二月时,我才需要将年份列增加 1。
empId name joiningDate derived Year
1049 Jithin 3/9/2009 2010
1017 Surya 1/2/2008 2009
1089 Bineesh 8/24/2009 2009
1090 Bless 7/15/2009 2010
1014 Dennis 1/5/2008 2009
1086 Sus 9/10/2009 2009
派生年份是必填列
我们可以通过下面的案例语句轻松实现这一点
Select *,
YEAR(joiningDate) + CASE WHEN MONTH(joiningDate) in (1,3,7,12) THEN 1 ELSE 0 END
from LUEmployee
但是现场PM又来了一个条件,不要用CASE语句,CASE效率低。 在寻找解决方案的过程中,我们得出了以下解决方案,一种使用二进制 K-map 的解决方案,如下
如果数字1到12代表从Jan到Dec的月份,看二进制结果
下面给出卡诺图的表达方式。
结果会是
我们需要用sql server二元运算来实现表达式
eg: binary of 12 = 1100
in the k-map, a = 1, b = 1, c = 0, d = 0
Similarly, binary of 7 = 0111
in the k-map, a = 0, b = 1, c = 1, d = 1
要获得最左边的位 (d),我们必须将位向右移动 3 个位置并屏蔽除 LSB 之外的所有位。
eg: ((MONTH(joiningDate)/8)&1)
类似地,左起第二位(c),我们需要将位向右移动2个位置,然后屏蔽除LSB之外的所有位
eg: ((MONTH(joiningDate)/4)&1)
最后,每个位可以表示为
so a = ((MONTH(joiningDate)/8)&1)
b = ((MONTH(joiningDate)/4)&1)
c = ((MONTH(joiningDate)/2)&1)
d = (MONTH(joiningDate)&1)
a inverse = (((MONTH(joiningDate)/8)&1)^1)
b inverse = (((MONTH(joiningDate)/4)&1)^1)
c inverse = (((MONTH(joiningDate)/2)&1)^1)
d inverse = ((MONTH(joiningDate)&1)^1)
最终代码将是
SELECT *,
YEAR(joiningDate) + CAST(
((MONTH(joiningDate)/8)&1)*((MONTH(joiningDate)/4)&1)*(((MONTH(joiningDate)/2)&1)^1)*((MONTH(joiningDate)&1)^1) |
(((MONTH(joiningDate)/8)&1)^1)*(((MONTH(joiningDate)/4)&1)^1)*(MONTH(joiningDate)&1) |
(((MONTH(joiningDate)/8)&1)^1)*((MONTH(joiningDate)/2)&1)*(MONTH(joiningDate)&1)
AS INT) [derivedYear]
FROM LUEmployee
结果会是
问题: 可能有简单和不太复杂的想法,请分享。
我喜欢找一个更简单的,也喜欢分享想法。这里可能的条件是12(12个月)。我们可以使用 k-map 来处理更多的条件。感觉 k-map 最多可以处理 64 个条件。
最佳答案
我的第一 react 是捍卫在这种情况下使用 case
子句。但是如果您绝对不允许使用它,也许您可以简单地添加一个包含月份和增量值的表:
LUMonthIncrement
Month Increment
1 1
2 0
3 1
4 0
5 0
6 0
7 1
8 0
9 0
10 0
11 0
12 1
然后您可以加入该表并添加增量:
Select LUEmployee.*,
YEAR(joiningDate) + LUMonthIncrement.Increment as derivedYear
from LUEmployee
join LUMonthIncrement on MONTH(LUEmployee.joiningDate) = LUMonthIncrement.Month
虽然这不太可能更高效,因为为了加入 LUMonthIncrement
,必须为LUEmployee
表。
关于sql - 在tsql中使用 bool 代数来避免CASE语句或处理复杂的WHERE条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23757036/