SQL SERVER2005 使用<>与!= 查询结果不一样的问题

本文介绍了一种在SQL查询中遇到的特殊问题,即当查询含有NULL值的数据时,使用&lt;&gt;或!=进行比较会得到错误结果的现象,并提供了解决方案。


我昨天测试一个东西,遇到了一个数据查询问题,让我非常郁闷与疑惑,非常不解。

问题是这样的,

有一张表叫STB,里面有1000条数据,有三个字段,分别为主键“机顶盒ID(STB_ID)”,“机顶盒条形码(STB_BAR_CODE)”,“机顶盒状态(STB_STATUS)”。

主键为identity(1,1)。条码与状态均为varchar类型。状态里只有1、2、3、4四种值。


--A 查询所有机顶盒为HS开头与00010开头的,一共有860个。

 select count(stb_id) from stb where stb_bar_code  like 'HS%'  or stb_bar_code like '00010%'

--A1 查询所有机顶盒为HS开头与00010开头的,机顶盒状态等于2的,有620个。

select count(stb_id) from stb where (stb_bar_code  like '%HS%'  or stb_bar_code like '%00010%') and stb_status = 2

--A2 查询所有机顶盒为HS开头与00010开头的,机顶盒状态不等于2的,按理说应该有860-620=240个,但结果确是238个,少了两个,哪去了?

select count(stb_id) from stb where (stb_bar_code  like '%HS%'  or stb_bar_code like '%00010%') and stb_status <> 2

非常不解啊,找了半天,终于找到原因了。


------------------------------------------------------------------------------------------------------------------------------------------------------------------

只有找出A里面没有包含A1,A2的机顶盒才能知道原因了,所以想了一个很傻的办法去左联查询。

select s1.stb_id,s1.stb_bar_code,s3.stb_bar_code,s5.stb_bar_code from (
	select * from stb s where stb_bar_code  like 'HS%'  or stb_bar_code like '00010%'
) as s1 
left join (
select s2.* from (
	select * from stb where (stb_bar_code  like '%HS%'  or stb_bar_code like '%00010%') and stb_status <> 2
) as s2 ) as s3
on s1.stb_id = s3.stb_id
left join (
	select s4.* from (
		select * from stb where (stb_bar_code  like '%HS%'  or stb_bar_code like '%00010%') and stb_status = 2
	) as s4 ) as s5
on s1.stb_id = s5.stb_id 
where (s1.stb_bar_code  like '%HS%'  or s1.stb_bar_code like '%00010%') and s3.stb_bar_code is null and s5.stb_bar_code is null order by s1.stb_bar_code

以上左联将<>2与=2均没有的数据查出来,果然有这2个。

问题找到了,原来是有些机顶盒状态为NULL,其中SQL中NULL值不能用<>与!=比较,这样结果是出不来的。

解决方式很简单,查询的时候将NULL转一下就行了。

<!-- 主查询:只查询主表信息 --> <select id="queryPurchaseOrderPage" resultType="com.hvlink.entity.dto.order.PurchaseOrderMainDTO"> SELECT m.id, m.company_code, m.purchase_order_no, m.publish_date, s.supplier_code, s.supplier_name, f.factory_code, f.factory_name, w.warehouse_code, w.warehouse_name, m.serial_version_num, m.order_type FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY purchase_order_no, company_code ORDER BY serial_version_num DESC) as rn FROM tb_order_main WHERE is_deleted = 0 ) m LEFT JOIN tm_supplier s ON m.supplier_code = s.supplier_code AND m.company_code = s.company_code LEFT JOIN tm_factory f ON m.factory_code = f.factory_code AND m.company_code = f.company_code LEFT JOIN tm_warehouse w ON m.warehouse_code = w.warehouse_code AND m.company_code = w.company_code <where> m.rn = 1 <!-- 只取每个订单的最新版本 --> <!-- 优化后的模糊匹配组 --> <if test="param.supplierName != null and param.supplierName != '' or param.supplierCode != null and param.supplierCode != '' or param.factoryName != null and param.factoryName != '' or param.factoryCode != null and param.factoryCode != '' or param.warehouseName != null and param.warehouseName != '' or param.warehouseCode != null and param.warehouseCode != ''"> AND ( <trim prefixOverrides="OR"> <!-- 供应商条件 --> <if test="param.supplierName != null and param.supplierName != ''"> OR s.supplier_name LIKE '%' + #{param.supplierName} + '%' </if> <if test="param.supplierCode != null and param.supplierCode != ''"> OR s.supplier_code LIKE '%' + #{param.supplierCode} + '%' </if> <!-- 工厂条件 --> <if test="param.factoryName != null and param.factoryName != ''"> OR f.factory_name LIKE '%' + #{param.factoryName} + '%' </if> <if test="param.factoryCode != null and param.factoryCode != ''"> OR f.factory_code LIKE '%' + #{param.factoryCode} + '%' </if> <!-- 仓库条件 --> <if test="param.warehouseName != null and param.warehouseName != ''"> OR w.warehouse_name LIKE '%' + #{param.warehouseName} + '%' </if> <if test="param.warehouseCode != null and param.warehouseCode != ''"> OR w.warehouse_code LIKE '%' + #{param.warehouseCode} + '%' </if> </trim> ) </if> <!-- 订单号模糊查询 --> <if test="param.purchaseOrderNo != null and param.purchaseOrderNo != ''"> AND m.purchase_order_no LIKE '%' + #{param.purchaseOrderNo} + '%' </if> <if test="param.startDate != null"> AND m.publish_date >= #{param.startDate} </if> <if test="param.endDate != null"> AND m.publish_date <= #{param.endDate} </if> <!-- 订单类型 --> <if test="param.orderType != null"> AND m.order_type = #{param.orderType} </if> <!-- 明细字段关联查询 - 使用EXISTS优化性能 --> <if test="param.partCode != null and param.partCode != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.part_code LIKE '%' + #{param.partCode} + '%' ) </if> <if test="param.partDesc != null and param.partDesc != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.part_desc LIKE '%' + #{param.partDesc} + '%' ) </if> <if test="param.frequency != null and param.frequency != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.frequency = #{param.frequency} ) </if> </where> ORDER BY s.supplier_code DESC, m.purchase_order_no DESC </select> <select id="selectLatestByOrderIds" resultType="com.hvlink.entity.dto.order.PurchaseOrderMainDTO"> SELECT m.id, m.company_code, m.purchase_order_no, m.publish_date, s.supplier_code, s.supplier_name, f.factory_code, f.factory_name, w.warehouse_code, w.warehouse_name, m.serial_version_num, m.order_type FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY purchase_order_no, company_code ORDER BY serial_version_num DESC) as rn FROM tb_order_main WHERE is_deleted = 0 AND id IN <foreach collection="orderIds" item="id" open="(" close=")" separator=","> #{id} </foreach> ) m LEFT JOIN tm_supplier s ON m.supplier_code = s.supplier_code AND m.company_code = s.company_code LEFT JOIN tm_factory f ON m.factory_code = f.factory_code AND m.company_code = f.company_code LEFT JOIN tm_warehouse w ON m.warehouse_code = w.warehouse_code AND m.company_code = w.company_code WHERE m.rn = 1 ORDER BY m.create_time DESC </select> 进行性能优化,并帮我检查是否有错误,条件需要原来的一样满足,我这是sqlserver,下面是明细表 <select id="queryDetailsByCompositeKeys" resultType="com.hvlink.entity.dto.order.PurchaseOrderDetailsDTO"> SELECT d.purchase_order_no, d.line_no, d.delivery_date, d.part_code, d.part_desc, d.unit, d.total_qty, d.required_qty, d.available_qty, d.shipped_qty, d.type, d.frequency, d.approval_code, d.serial_version_num, d.company_code, d.order_type FROM tb_order_detail d WHERE EXISTS ( SELECT 1 FROM ( VALUES <foreach collection="compositeKeys" item="item" separator=","> (#{item.purchaseOrderNo}, #{item.companyCode}, #{item.serialVersionNum}) </foreach> ) AS keys(purchase_order_no, company_code, serial_version_num) WHERE d.purchase_order_no = keys.purchase_order_no AND d.company_code = keys.company_code AND d.serial_version_num = keys.serial_version_num ) ORDER BY d.purchase_order_no DESC, d.line_no ASC, d.delivery_date DESC </select>
最新发布
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值