T-sql案例返回错误的值

时间:2013-03-18 21:52:44

标签: sql sql-server tsql

我正在努力让我的SQL查询工作。当我的失败找到一行时,我想返回一行,就像图片中那样,但我想将ifuserholdscertificate设置为'NO'。

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计数中的一个,总是'是'

3 个答案:

答案 0 :(得分:1)

你可能会得到空值而不是你没有考虑的零。我会尝试这样做:

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

我不明白为什么你说人们得到2然后会计为零而且期待一个“不”。回答。如果没有您收集的源数据的感觉,在引用它之前很难知道数据是什么样的。您正在使用窗口函数(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

答案 1 :(得分: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

在这里您可以获得pubs和Northwind数据库。 这很有用,因为大多数开发人员已经安装了这些数据库(和AdventureWorks)来解决这种情况。

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

答案 2 :(得分: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;