比较SQL比较中的null

时间:2011-01-29 18:30:17

标签: sql sybase

我正在用VB6创建一个前端,我的数据库是Sybase。使用DSN我创建了一些小的exe来填充网格中的报表。它工作正常。

但是,如果我使用以下查询,我只得到小时和已回答的数据。如果我在SQL查询中执行查询,则完成数据即将到来。

我相信总和(如果在VB6中不起作用,请指导我替代。

"select datepart (hh, callstartdt) as Hour, " _
    & " count(seqnum) as Anaswered," _
    & " sum(case when user_id <> NULL then 1 else 0 end) as answered_calls ," _
    & " sum(case when user_id <> NULL and  datediff (ss, callstartdt, QueueEndDt) <= 20 then 1 else 0 end) , " _
    & " sum(case when user_id = NULL then 1 else 0 end), " _
    & " sum(case when user_id <> NULL and datediff (ss, callstartdt, QueueEndDt) <= 20 then 1 else 0 end)  / count(seqnum), " _
    & " sum(Case when user_id <> NULL then 1 else 0 end ) / count(seqnum) from acdcalldetail " _
    & " where callstartdt between '" & fromDt & "' and '" & toDt & "' " _
    & " and service_id not in (37,39,47,51,57,58,96,215,374,375) " _
    & " group by datepart (hh, callstartdt) " _
    & " order by datepart (hh, callstartdt)"

5 个答案:

答案 0 :(得分:6)

您无法使用when user_id <> Null。您必须使用user_id Is Nulluser_id Is Not Null。任何=或&lt;&gt;为Null导致Unknown,对于Case表达式将其视为false。

答案 1 :(得分:1)

我猜对于sysbase,它与sql-server相同。

有一个设置可以在(旧的?)sybase默认值

之间切换
set ansi_nulls off

select case when null = null then 1 else 0 end
-- returns 1

和ansi的行为。

set ansi_nulls on

select case when null = null then 1 else 0 end
-- returns 0

今天问题不在于哪种设置更优雅,而是哪种设置会带来更多麻烦。

答案 2 :(得分:0)

一般规则:任何涉及NULL的操作都会产生NULL。无论测试是否为正('==')或否定('&lt;&gt;'),涉及NULL的所有比较都会失败。唯一的例外是通过IS [NOT] NULL或使用COALESCE()/ ISNULL()来显示无效性。

答案 3 :(得分:0)

Nicholas,我同意你的意见,因为对null的比较应该总是假的,但是我在ASE 15.0.3服务器上尝试了以下代码并得到了令人惊讶的结果

declare @xx int
select @xx = null
select @xx
select 1 where null = @xx

对于我没想到的第二个选择,它返回1 ..

答案 4 :(得分:0)

只是让你知道count(seqnum),因为Answered不是Aspect UIP入站呼叫应答的正确定义。如果您检查标记为SwitchDispId的字段,则其中可能包含1或2,这相当于放弃调用。因此,没有接听电话。我确实看到你使用user_id not null来接听电话,但我只是想让你知道这一点。

此外,您可以将acdcalldetail表加入服务表,以获得看起来更像是业务用途的名称:

SELECT 
     Service_c
    ,SUM(CASE WHEN acd.SwitchDispID IN (1,2) THEN 1 ELSE 0 END as Abandons
    ,SUM(CASE WHEN acd.user_id is not null THEN 1 ELSE 0 END as Answered
FROM acdcalldetail acd
JOIN service s
    ON s.service_id = acd.service_id
    AND s.sourceid = acd.sourceid
WHERE acd.CallStartDt between '20170501' AND '20170530'
AND s.Service_id NOT IN  (37,39,47,51,57,58,96,215,374,375)
GROUP BY 
    s.Service_c

"select datepart (hh, callstartdt) as Hour, " _
    & " count(seqnum) as Anaswered," _
    & " sum(case when user_id <> NULL then 1 else 0 end) as answered_calls ," _
    & " sum(case when user_id <> NULL and  datediff (ss, callstartdt, QueueEndDt) <= 20 then 1 else 0 end) , " _
    & " sum(case when user_id = NULL then 1 else 0 end), " _
    & " sum(case when user_id <> NULL and datediff (ss, callstartdt, QueueEndDt) <= 20 then 1 else 0 end)  / count(seqnum), " _
    & " sum(Case when user_id <> NULL then 1 else 0 end ) / count(seqnum) from acdcalldetail " _
    & " where callstartdt between '" & fromDt & "' and '" & toDt & "' " _
    & " and service_id not in (37,39,47,51,57,58,96,215,374,375) " _
    & " group by datepart (hh, callstartdt) " _
    & " order by datepart (hh, callstartdt)"