复杂SQL与Where子句连接
由于对SQL非常陌生,我请求您耐心等待。我一直在绞尽脑汁想办法通过连接3个表来创建这个视图。我将使用模拟表等来保持这一点非常简单。这样我就可以试着理解答案了——不只是复制和粘贴 ICS_用品:复杂SQL与Where子句连接,sql,subquery,left-join,inner-join,Sql,Subquery,Left Join,Inner Join,由于对SQL非常陌生,我请求您耐心等待。我一直在绞尽脑汁想办法通过连接3个表来创建这个视图。我将使用模拟表等来保持这一点非常简单。这样我就可以试着理解答案了——不只是复制和粘贴 ICS_用品: Supplies_ ID Item_Description ------------------------------------- 1 | PaperClips 2 | Rubber Bands
Supplies_ ID Item_Description
-------------------------------------
1 | PaperClips
2 | Rubber Bands
3 | Stamps
4 | Staples
ICS_订单:
ID SuppliesID RequisitionNumber
----------------------------------------------------
1 | 1 | R1234a
6 | 4 | R1234a
2 | 1 | P2345b
3 | 2 | P3456c
4 | 3 | R4567d
5 | 4 | P5678e
ICS_交易:
ID RequsitionNumber OrigDate TransType OpenClosed
------------------------------------------------------------------
1 | R1234a | 06/12/20 | Req | Open
2 | P2345b | 07/09/20 | PO | Open
3 | P3456c | 07/14/20 | PO | Closed
4 | R4567d | 08/22/20 | Req | Open
5 | P5678e | 11/11/20 | PO | Open
这就是我想在我的观点中看到的结果
Supplies_ID Item RequsitionNumber OriginalDate TransType OpenClosed
---------------------------------------------------------------------------------------
1 | Paper Clips | P2345b | 07/09/20 | PO | OPEN
2 | Rubber Bands | Null | Null | Null | Null
3 | Stamps | Null | Null | Null | Null
4 | Staples | P56783 | 11/11/20 | PO | OPEN
我就是到不了那里。我希望始终拥有与ICS_Supplies表中相同数量的记录。我需要加入ICS_Orders表以获取申请编号,因为这是我需要加入ICS_Transactions表的内容。我不想在新添加的字段中看到数据,除非ICS_Transactions.TransType='PO'和ICS_Transactions.OpenClosed='OPEN',否则连接的字段应该被视为null,不管它们包含什么。如果可能的话
我的研究表明,这可能是一个左连接,这对我来说是非常新的。我自己做了很多尝试,然后昨天把我的问题发了出来。但我一直在努力问正确的问题,其他成员建议我再次发帖
如果需要,我可以分享我所做的,但我担心这会让事情变得过于混乱,因为我走错了方向
我为那些需要一些背景信息的人添加了一个原始问题的链接
如果需要任何其他信息,请询问。如果我遗漏了任何需要的详细信息,我会提前向您道歉。此查询将返回供应数据。左连接将添加所有具有supply_id的订单(对于没有的订单,返回null) 如果记录不存在,null值将自动显示null。例如,您正在加入Transactions表,如果该供应没有事务id,那么它将返回“null”
修改您的查询,运行它,然后如果可能的话,也许可以使用真实的示例更新您的问题。这有点棘手,因为您想根据第三个表中是否有匹配项排除第二个表中的行-因此两个
左联接
不是您想要的
我认为这实现了您想要的逻辑:
select s.supplies_id, s.item_description,
t.requisition_number, t.original_date, t.trans_type, t.open_closed
from ics_supplies s
left join ics_transaction t
on t.transtype = 'PO'
and t.open_closed = 'Open'
and exists (
select 1
from ics_order o
where o.supplies_id = s.supplies_id and o.requisition_number = t.requisition_number
)
另一种表达方式是子查询中的内部联接
,然后是左联接
:
select s.supplies_id, s.item_description,
t.requisition_number, t.original_date, t.trans_type, t.open_closed
from ics_supplies s
left join (
select o.supplies_id, t.*
from ics_order o
inner join ics_transaction t
on t.requisition_number = o.requisition_number
where t.transtype = 'PO' and t.open_closed = 'Open'
) t on t.supplies_id = s.supplies_id
你在最初的问题中写道: “我只需要ICS_Transactions表中的一条匹配记录。 理想情况下,我想要的是最新的 “ICS_交易。原始日期”。” 因此,目标是获取TransType为“PO”且OpenClosed为“Open”的最新事务。本规范中CTE“oa_CTE”的目的。然后,在SuppliesId上加入适当的事务。像这样的
with oa_cte(SuppliesId, RequsitionNumber, OriginalDate,
TransType, OpenClosed, RowNum) as (
select o.SuppliesId, o.RequsitionNumber,
t.OrigDate, t.TransType, t.OpenClosed,
row_number() over (partition by o.SuppliesId
order by t.OrigDate desc)
from ICS_Orders o
join ICS_Transactions t on o.RequisitionNumber=t.RequisitionNumber
where t.TransType='PO'
and t.OpenClosed='OPEN')
select s.*, oa.*
from ICS_Supplies s
left join oa_cte oa on s.SuppliesId=oa.SuppliesId
and oa.RowNum=1;
显示您的左连接尝试。@jarlh-我之所以没有发布它,是因为我与我的原始问题、原始左连接以及我以前所做的所有工作共享了一个链接。我觉得在这里复制这些东西不是一个好的做法。相反,我分享了一个链接——正如我的帖子所说。不管怎样,现在已经有答案了,但是谢谢你的帮助!是的,你是对的。从发布最初的问题到现在,我了解到的一件事是,我了解到,对于同一个供应项目,从来不会同时有两个未结采购订单。因此。我可能错误地把事情弄得比需要的更复杂。我可能会不顾一切地执行此操作,以保护视图的完整性。随着应用程序的不断变化。这是一个20年前创建的老应用程序,表中有拼写错误和不良做法。我需要投入一些时间来清理它并确保安全谢谢你发布此回复。第一个例子中的逻辑很容易理解(对于新手来说),它带来了我所期望的结果。感谢您在连接后应用WHERE子句,此时NULLs将不满足条件,被排除,并将外部连接转换为内部连接。
with oa_cte(SuppliesId, RequsitionNumber, OriginalDate,
TransType, OpenClosed, RowNum) as (
select o.SuppliesId, o.RequsitionNumber,
t.OrigDate, t.TransType, t.OpenClosed,
row_number() over (partition by o.SuppliesId
order by t.OrigDate desc)
from ICS_Orders o
join ICS_Transactions t on o.RequisitionNumber=t.RequisitionNumber
where t.TransType='PO'
and t.OpenClosed='OPEN')
select s.*, oa.*
from ICS_Supplies s
left join oa_cte oa on s.SuppliesId=oa.SuppliesId
and oa.RowNum=1;