2009-01-06 82 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