2013-03-18 69 views
0

我努力讓我的SQL查詢工作。當我的IN FAILS找到一行時,我想返回一行,就像圖片中的行一樣,但是我想將ifuserholdscertificate設置爲「NO」。T-sql case返回錯誤值

SELECT tuc.id, 
     tu.firstName, 
     tuc.uid, 
     tuc.value, 
     tc.name, 
     count(tuc.value) over (PARTITION BY tuc.uid) AS 'amount', 
     'certificate DESIRABLE' AS 'typeofthing' , 
     'YES' AS 'HasorNot', 
     ifuserholdscertificate = CASE 
            WHEN count(tuc.value) = 0 THEN 'NO' 
            ELSE 'YES' 
           END 
FROM t_user_certificates tuc, 
    t_certificates tc, 
    t_users tu 
WHERE tuc.value IN (4, 
        12, 
        31) 
    AND tuc.value = tc.id 
    AND tu.id = tuc.uid 
GROUP BY tuc.id, 
     tu.firstName, 
     tuc.uid, 
     tuc.value, 
     tc.name 

這是查詢生成的數據!

enter image description here 正如你可以看到,即使有些人只有在金額行中得到2,它仍然不會獲取一行並將ifuserholdscertificate設置爲'NO'。

根據要求更新!

select tuc.id, 
count(tuc.value) as 'counten', 
tu.firstName, 
tuc.uid, 
tuc.value, 
tc.name, 
count(tuc.value) over (PARTITION BY tuc.uid) as 'amount', 
'certificateDESIRABLE' as 'typeofthing' , 
'YES' as 'HasorNot', 
HasOrders = CASE 
       WHEN count(tuc.value) = 0 THEN 'NO' 
       ELSE 'YES' 
      END 
from t_user_certificates tuc     
left outer join t_certificates tc 
on tuc.value = tc.id 
left outer join t_users tu 
on tu.id = tuc.uid 
GROUP BY tuc.id, tu.firstName, tuc.uid, tuc.value, tc.name 

enter image description here

Alwyas一個1伯爵始終 'YES'

+0

添加圖片最初沒有顯示 – 2013-03-18 21:54:25

+0

您的查詢可能不太好...你可以用正常的連接子句連接表......如果你顯示所有三個表和你想要的結果,會更好。 – Justin 2013-03-18 22:02:00

+0

downvote寫一個壞的查詢?這是苛刻的..所以有一個問題可以賺你一票。 – 2013-03-18 22:08:18

回答

1

這可能是更喜歡你在找什麼。你總是返回1,並且沒有用戶沒有證書,因爲你在where子句中有IN位。因此,即使使用外部聯接,也只能使用這些值從t_user_certificates返回行。它有效地成爲一個內部連接。 ANSI連接語法是你的朋友。它將JOIN邏輯從過濾器中分離出來。

SELECT tuc.id, 
     tu.firstName, 
     tuc.uid, 
     tuc.value, 
     tc.name, 
     count(tuc.value) AS 'amount', 
     'certificate DESIRABLE' AS 'typeofthing' , 
     'YES' AS 'HasorNot', 
     ifuserholdscertificate = CASE 
            WHEN count(tuc.value) > 0 THEN 'YES' 
            ELSE 'NO' 
           END 
FROM 
    t_users tu 
LEFT JOIN t_user_certificates tuc 
    ON 
    tu.id = tuc.uid 
    AND 
    tuc.value IN 
    (
     4 
     , 12 
     , 31 
    ) 
LEFT JOIN 
    t_certificates tc 
    ON 
    tuc.value = tc.id 

GROUP BY tuc.id, 
     tu.firstName, 
     tuc.uid, 
     tuc.value, 
     tc.name; 
+0

Cool Jason!沒有想到它那樣!謝謝一堆! – 2013-03-19 18:46:38

1

你可能會得到空值,而不是零,你不佔。我反而試試這個:

ifuserholdscertificate = CASE         
    WHEN (count(tuc.value) = 0 or count(tuc.Value) = null) THEN 'NO' 
    ELSE 'YES' 
    END 

我沒有得到爲什麼就表示人得到2雖然然後佔零和期待一個「NO」的回答。如果不瞭解所收集的源數據,很難在引用它之前知道數據的外觀。你也使用了一個窗口函數(over(partion by ..)),它會給出與常規計數函數不同的數據。如果您的目標是在窗口函數上使用表達式時需要使用一種情況,那麼您必須先執行嵌套select或cte來先獲取數字,然後再對其進行邏輯處理。

事情是這樣的:

declare @Person Table (personID int identity, person varchar(8)); 

insert into @Person values ('Brett'),('Sean'),('Chad'); 

declare @Orders table (OrderID int identity, PersonID int, Desciption varchar(32), Amount int); 

insert into @Orders values (1, 'Shirt', 20),(2, 'Shirt', 22),(2, 'Shoes', 52); 

With a as 
    (
    Select 
     p.person 
    , count(o.orderID) over(partition by person) as Count 
    from @Person p 
     left join @Orders o on p.personID = o.PersonID 
    ) 
select 
    person 
, case when Count = 0 then 'No' else cast(Count as varchar(8)) end as Count 
from a 
+0

我最終仍然是所有行都是YES – 2013-03-18 22:39:24

+0

查看我的更新。我認爲,由於你期望得到的和你的邏輯以及處理select語句中的窗口函數和常規邏輯混合在一起,你遇到了問題。您可以隨時添加'Count(tuc.value)'列來調試正在進行的範圍不正確的事情。 – djangojazz 2013-03-18 22:46:52

+0

嗯我試過我的計數總是返回1. 我該如何用我的代碼做你的例子?我可以讓它工作? – 2013-03-18 23:07:46

1

到您的查詢添加列調試。並用你的屏幕截圖顯示這些結果。

MyCOUNT = count(tuc.value), 

我的Northwind示例工作正常。當父母客戶沒有訂單(行)時,我得到「否」。

................

Use Northwind 
GO 

Select 
    custs.CustomerID, 
    MyCOUNT = count(ords.OrderID), 
    HasOrders = CASE 
     WHEN count(ords.OrderID) = 0 THEN 'NO' 
     ELSE 'YES' 
    END 
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID 
GROUP BY 
    custs.CustomerID 
order by 2 

這裏有一些額外的查詢顯示上的是什麼打算:

Select Label = 'You get no results here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID 
Where 
    ords.OrderID IS NULL 


Select Label = 'You get Customers with no Orders here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID 
Where 
    ords.OrderID IS NULL 


Select Label = 'You get Customers with or without Orders here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID 

在這裏你可以得到酒吧和Northwind數據庫。 這很有幫助,因爲大多數開發人員已經安裝了這些數據庫(和AdventureWorks)來處理這種情況。

http://msdn.microsoft.com/en-us/library/ms143221(v=sql.105).aspx

+0

對不起,我認爲你原來的COUNT。我的錯。 – granadaCoder 2013-03-18 22:57:54

+0

如何將我的IN語句轉換爲外連接? – 2013-03-18 23:05:10

+0

我並不是建議切換到「外連接」。我顯示當有現在行時,COUNT函數仍然帶回0. – granadaCoder 2013-03-19 13:05:34