SQL:两表关联取舍时, is null 判断只能单独存在

本文探讨了SQL中量表关联的正确实践,强调了isnull判断的独立使用原则,对比了错误与正确的SQL语句写法,指导如何高效且准确地进行数据筛选。

SQL:量表关联取舍时, is null 判断只能单独存在,不能与其他判断同时进行。

 

  • 错误的写法:

select 
a.user_id
,a.uid
,a.page_type
,a.d

from
(
    select 
    o.user_id
    ,f.uid
    ,f.page_type
    ,f.d
    from dw_busdb.for_flow_conversion_report_distinguish_regular_fresh_customers f
    right join dw_busdb.tbl_order o
    on o.d = f.d  and  o.user_id = f.uid 
    where f.d = '2019-08-05'    ---这边的写法也不好,最好写嵌套20190807
    and f.page_type = 'list'   
    and to_date(o.create_dttm) = '2019-08-05'
    and f.uid is not  null  
  	and f.uid <> '' --''不考虑20190806
    and (o.user_id is not null and o.user_id <> '')  -- 订单表本身不为null
)a
left join dw_busdb.for_flow_conversion_report_distinguish_regular_fresh_customers f_pkg
on  a.user_id = f_pkg.uid and a.d = f_pkg.d
where f_pkg.page_type = 'servicePkg'  -- 这样的写法是错误的
	and f_pkg.uid is null  
  • 正确的写法:
select 
distinct a.user_id

from
(
    select 
    o.user_id

    from dw_busdb.for_flow_conversion_report_distinguish_regular_fresh_customers f
    join dw_busdb.tbl_order o  -- join会默认跳过null数据
    on o.d = f.d  and  o.user_id = f.uid 
    where f.d = '2019-08-06'   -- 这样写效率不高,最好先写子查询,也能有效避免出错
    and f.page_type = 'list'
    and to_date(o.create_dttm) = '2019-08-06'

  	and f.uid <> '' --''不考虑20190806
   	and order_business_type = 'bus'

)a


left join 
(select  f_pkg.uid
from 
dw_busdb.for_flow_conversion_report_distinguish_regular_fresh_customers f_pkg
 where  f_pkg.d = '2019-08-06'
and  f_pkg.page_type = 'servicePkg'
 )b
on a.user_id = b.uid
where b.uid is null  -- 此处判断没问题,null判断不能与其他判断同时存在。

 

SELECT q.NumAtCard, q.ItemCode, MAX(q.U_SaleContNo) AS U_SaleContNo, MAX(q.U_PONum) AS U_PONum, SUM(q.报价单数量) AS 报价单总数量, COALESCE(SUM(d.到货数量), 0) AS 到货总数量, COALESCE(SUM(r.退货数量), 0) AS 退货总数量, COALESCE(SUM(c.贷项数量), 0) AS 贷项总数量, COALESCE(SUM(d.到货数量), 0) - COALESCE(SUM(r.退货数量), 0) - COALESCE(SUM(c.贷项数量), 0) AS 到货数量, SUM(q.报价单数量) - COALESCE(SUM(d.到货数量), 0) + COALESCE(SUM(r.退货数量), 0) + COALESCE(SUM(c.贷项数量), 0) AS 在途数量 FROM ( SELECT n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode, SUM(n1.Quantity) AS 报价单数量, CASE WHEN n1.U_SaleContNo IS NOT NULL THEN 'SALE' WHEN n1.U_PONum IS NOT NULL THEN 'PO' ELSE 'NONE' END AS LinkType FROM SINO_SAP.dbo.OPQT n LEFT JOIN SINO_SAP.dbo.PQT1 n1 ON n.DocEntry = n1.DocEntry LEFT JOIN SINO_SAP.dbo.OUDP p ON n1.U_Department = p.Name WHERE n.CANCELED = 'n' AND p.Remarks = '经销体系' AND COALESCE(n.NumAtCard, n1.U_PurContNo) IS NOT NULL AND n.DocDate >= '2024-01-01' GROUP BY n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode ) q LEFT JOIN ( SELECT n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode, SUM(n1.Quantity) AS 到货数量, CASE WHEN n1.U_SaleContNo IS NOT NULL THEN 'SALE' WHEN n1.U_PONum IS NOT NULL THEN 'PO' ELSE 'NONE' END AS LinkType FROM SINO_SAP.dbo.OPDN n LEFT JOIN SINO_SAP.dbo.PDN1 n1 ON n.DocEntry = n1.DocEntry LEFT JOIN SINO_SAP.dbo.OUDP p ON n1.U_Department = p.Name WHERE n.CANCELED = 'n' AND p.Remarks = '经销体系' AND COALESCE(n.NumAtCard, n1.U_PurContNo) IS NOT NULL AND n.DocDate >= '2024-01-01' GROUP BY n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode ) d ON q.NumAtCard = d.NumAtCard AND q.ItemCode = d.ItemCode AND ( (q.LinkType = 'SALE' AND d.LinkType = 'SALE' AND q.U_SaleContNo = d.U_SaleContNo) OR (q.LinkType = 'PO' AND d.LinkType = 'PO' AND q.U_PONum = d.U_PONum) OR (q.LinkType = 'NONE' AND d.LinkType = 'NONE') ) LEFT JOIN ( SELECT n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode, SUM(n1.Quantity) AS 退货数量, CASE WHEN n1.U_SaleContNo IS NOT NULL THEN 'SALE' WHEN n1.U_PONum IS NOT NULL THEN 'PO' ELSE 'NONE' END AS LinkType FROM SINO_SAP.dbo.ORPD n LEFT JOIN SINO_SAP.dbo.RPD1 n1 ON n.DocEntry = n1.DocEntry LEFT JOIN SINO_SAP.dbo.OUDP p ON n1.U_Department = p.Name WHERE n.CANCELED = 'n' AND p.Remarks = '经销体系' AND COALESCE(n.NumAtCard, n1.U_PurContNo) IS NOT NULL AND n.DocDate >= '2024-01-01' GROUP BY n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode ) r ON q.NumAtCard = r.NumAtCard AND q.ItemCode = r.ItemCode AND ( (q.LinkType = 'SALE' AND r.LinkType = 'SALE' AND q.U_SaleContNo = r.U_SaleContNo) OR (q.LinkType = 'PO' AND r.LinkType = 'PO' AND q.U_PONum = r.U_PONum) OR (q.LinkType = 'NONE' AND r.LinkType = 'NONE') ) LEFT JOIN ( SELECT n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode, SUM(n1.Quantity) AS 贷项数量, CASE WHEN n1.U_SaleContNo IS NOT NULL THEN 'SALE' WHEN n1.U_PONum IS NOT NULL THEN 'PO' ELSE 'NONE' END AS LinkType FROM SINO_SAP.dbo.ORPC n LEFT JOIN SINO_SAP.dbo.RPC1 n1 ON n.DocEntry = n1.DocEntry LEFT JOIN SINO_SAP.dbo.OUDP p ON n1.U_Department = p.Name WHERE n.CANCELED = 'n' AND p.Remarks = '经销体系' AND COALESCE(n.NumAtCard, n1.U_PurContNo) IS NOT NULL AND n.DocDate >= '2024-01-01' GROUP BY n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode ) c ON q.NumAtCard = c.NumAtCard AND q.ItemCode = c.ItemCode AND ( (q.LinkType = 'SALE' AND c.LinkType = 'SALE' AND q.U_SaleContNo = c.U_SaleContNo) OR (q.LinkType = 'PO' AND c.LinkType = 'PO' AND q.U_PONum = c.U_PONum) OR (q.LinkType = 'NONE' AND c.LinkType = 'NONE') ) WHERE q.LinkType <> 'NONE' GROUP BY q.NumAtCard, q.ItemCode HAVING SUM(q.报价单数量) - COALESCE(SUM(d.到货数量), 0) + COALESCE(SUM(r.退货数量), 0) + COALESCE(SUM(c.贷项数量), 0) > 0; 这个代码是可以的,现在还要增加一个功能,功能就是到货数据回填,因为我们已经计算出来到货数量了,并且通过n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode可以确定对应的是pqt1的那一行,PQT1这一行还有一个U_ArrQty字段,需要将到货数量回填到这个字段中,现在我能想到的问题就是到货数量可能比本身这一行的n1.Quantity要多,这种情况下,代这个单据还有一行相同的n.NumAtCard, n1.U_SaleContNo, n1.U_PONum, n1.ItemCode,需要将到货数量拆分写入到U_ArrQty,要注意我们现在在计算到货数量的候,报价单数量使用的临q,用了分组聚合,回填的候不可以聚合,可以通过oqt1的linenum记录具体写入了哪一行
最新发布
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值