2009-01-06 83 views
3

首先查看此代码。我似乎应该为我工作,但它不是! (惊喜!)如何在TSQL中创建布尔型计算字段并加入该计算字段?

无论如何,这是我第一次尝试:

SELECT 
Status as status, 
Address as ip, 
PCName as pc_name, 
(Numbers.Phone = 'CPU/' + PCName) as cpu_contact, 
(Numbers.Phone = 'PC/' + PCName) as pc_contact, 
(Numbers.Phone = 'LOGIN/' + PCName) as login_contact, 
FROM IPAddress 
WHERE $where --Generated In code 
JOIN Numbers 
    ON ('CPU/' + PCName = Numbers.Phone) 
    OR ('PC/' + PCName = Numbers.Phone) 
    OR ('LOGIN/' + PCName = Numbers.Phone) 

所以,我要的是一些布尔计算字段并加入类似的条件。我也想将结果折叠成单行。举例来说,我认为目前的设置会做这样的事情:

status ip cpu_contact pc_contact login_contact 
----------------------------------------------- 
foo bar true  false  false 
foo bar false  true  false 
foo bar false  false  true 

而且很明显,我宁愿

status ip cpu_contact pc_contact login_contact 
----------------------------------------------- 
foo bar true  true  true 

任何想法?数据库重新设计不是一种选择。如果是这样,我会这么做:-)

回答

4

你可以使用一个GROUP BYSUM塌陷行:

SELECT 
    Status as status, Address as ip, PCName as pc_name, 
    cast(sum(case when (Numbers.Phone = 'CPU/' + PCName) then 1 else 0 end) as bit) 
    as cpu_contact, 
    cast(sum(case when (Numbers.Phone = 'PC/' + PCName) then 1 else 0 end)) as bit) 
    as pc_contact, 
    cast(sum(case when (Numbers.Phone = 'LOGIN/' + PCName) then 1 else 0 end) as bit) 
    as login_contact, 
FROM 
    IPAddress 
    JOIN Numbers ON 
     ('CPU/' + PCName = Numbers.Phone) OR ('PC/' + PCName = Numbers.Phone) OR 
     ('LOGIN/' + PCName = Numbers.Phone) 
WHERE 
    $where --Generated In code 
GROUP BY 
    Status, Address, PCName 

既然你正在做一个逻辑或行之间,一个零的总和是假的,而任何大于0的值都是真的。

+0

哇,这太复杂了!好吧。我认为它会完成工作;它也很糟糕,因为我们有很多列没有列出,但我宁愿程序的一部分比所有部分都复杂。谢谢! – 2009-01-06 18:27:25

1

您需要使用Case/When进行比较。在这种情况下,我硬编码为1或0,但T-SQL会将硬编码的数字转换为int。如果你想布尔(位),则需要手动转换,像这样......

Convert(Bit, Case When Numbers.Phone = 'CPU/' + PCName Then 1 Else 0 End) as cpu_contact, 
Convert(Bit, Case When Numbers.Phone = 'PC/' + PCName Then 1 Else 0 End) as pc_contact, 
Convert(Bit, Case When Numbers.Phone = 'LOGIN/' + PCName Then 1 Else 0 End) as login_contact, 
1
SELECT 
Status as status, 
Address as ip, 
PCName as pc_name, 
case when sum(case when Numbers.Phone = 'CPU/' + PCName then 1 end) > 0 then 'true' else 'false' end as cpu_contact, 
case when sum(case when Numbers.Phone = 'PC/' + PCName then 1 end) > 0 then 'true' else 'false' end as pc_contact, 
case when sum(case when Numbers.Phone = 'LOGIN/' + PCName then 1 end) > 0 then 'true' else 'false' end as login_contact 
FROM IPAddress 
JOIN Numbers 
    ON ('CPU/' + PCName = Numbers.Phone) 
    OR ('PC/' + PCName = Numbers.Phone) 
    OR ('LOGIN/' + PCName = Numbers.Phone) 
WHERE -- your condition goes here 
group by status, address, pc_name