我有一个返回工作日的查询
Select PERSON_NAME, PERSON_DAY from PERSON_DAYS WHERE PERSON_ID = @myId
说我得到
John 1 (mo)
John 3 (mo tu)
John 8 (th)
我需要整天忙着为约翰争取。如何在此查询中对 PERSON_DAY 列进行逻辑或?
结果应该是 11 (mo tu th)
我有一个返回工作日的查询
Select PERSON_NAME, PERSON_DAY from PERSON_DAYS WHERE PERSON_ID = @myId
说我得到
John 1 (mo)
John 3 (mo tu)
John 8 (th)
我需要整天忙着为约翰争取。如何在此查询中对 PERSON_DAY 列进行逻辑或?
结果应该是 11 (mo tu th)
到目前为止我最好的
;with PowersOf2
as
(
select 1 as Number
union all
select A.Number * 2 from PowersOf2 as A where A.Number < 64
)
select P.PERSON_NAME, sum(distinct P.PERSON_DAY & PowersOf2.Number)
from PERSON_DAYS as P
left outer join PowersOf2 on PowersOf2.Number <= P.PERSON_DAY
where P.PERSON_ID = @myId
group by P.PERSON_NAME
如果我理解正确,您可以结合使用按位运算符 and
和聚合函数sum
来做您想做的事情。
例子:
with person_days as (
select 'John' as person_name, 1 as weekday --mo
union select 'John', 3 -- mo, tu
union select 'John', 8 -- th
union select 'Jane', 1 -- mo
union select 'Jane', 9 -- mo, th
union select 'Jane', 40 -- th, sa
),
Bits AS (
SELECT 1 AS BitMask --mo
UNION ALL SELECT 2 --tu
UNION ALL SELECT 4 --we
UNION ALL SELECT 8 --th
UNION ALL SELECT 16 --fr
UNION ALL SELECT 32 --sa
UNION ALL SELECT 64 --su
UNION ALL SELECT 128
)
, person_single_days as (
select distinct person_name, weekday & bits.BitMask single_weekday
from person_days
inner join bits on person_days.weekday & bits.BitMask > 0
)
select person_name, sum(single_weekday) weekdays
from person_single_days
group by person_name;
结果:
person_name weekdays
----------- -----------
Jane 41
John 11
受到 Roman 的 CTE 的“启发”:(请注意,第一个 CTE 只是生成演示数据)
with p as
(
select 'John' as PERSON_NAME, 1 as PERSON_DAY
union
select 'John', 3
union
select 'John', 8
union
select 'Jane', 2
union
select 'Jane', 4
),
cte as
(
select PERSON_NAME, PERSON_DAY from p
union all
select cte2.PERSON_NAME, p.PERSON_DAY | cte2.PERSON_DAY
from p
inner join cte as cte2 on p.PERSON_NAME = cte2.PERSON_NAME
where p.PERSON_DAY & cte2.PERSON_DAY = 0
)
select PERSON_NAME, MAX(PERSON_DAY) from cte
group by PERSON_NAME
我认为您正在寻找的是执行 OR 的自定义聚合。您可以在 .NET 中使用 SQL CLR 编写它。这可能是最干净的解决方案。它也可以重复使用。
或者,您可以使用基于游标的循环来计算结果。
您也可以(误)使用 CTE 来达到此目的。