我正在努力让我的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
这是查询生成的数据!
正如你所看到的那样,即使某些人只在金额行中获得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
Alwyas计数中的一个,总是'是'
答案 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;