0

我正在努力让我的 SQL 查询正常工作。当我无法找到一行时,我想返回一行,就像图片中的行一样,但我希望将 ifuserholdscertificate 设置为“否”。

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

这是查询生成的数据!

在此处输入图像描述 正如您所看到的,即使有些人在金额行中只得到 2,它仍然不会获取一行并将 ifuserholdscertificate 设置为“否”。

根据要求更新!

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

在此处输入图像描述

计数中总是一个 1 并且总是“是”

4

3 回答 3

1

您可能会得到空值而不是您没有考虑的零值。我会试试这个:

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

我不明白你为什么说人们得到 2,然后占零并期待一个“不”的答案。如果不了解您正在收集的源数据,就很难在引用之前知道数据的样子。您也在使用窗口函数( over(partion by..) ),这将提供与常规计数函数不同的数据。如果您的目标是在窗口函数上使用 case when 表达式,则必须先执行嵌套 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
于 2013-03-18T22:28:50.450 回答
1

在查询中添加一列以进行调试。并用您的屏幕截图显示这些结果。

MyCOUNT = count(tuc.value),

我的罗斯文示例工作正常。当父客户没有订单(行)时,我得到“否”。

......

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

于 2013-03-18T22:51:14.313 回答
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;
于 2013-03-19T15:23:14.787 回答