Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
复杂SQL与Where子句连接_Sql_Subquery_Left Join_Inner Join - Fatal编程技术网

复杂SQL与Where子句连接

复杂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

由于对SQL非常陌生,我请求您耐心等待。我一直在绞尽脑汁想办法通过连接3个表来创建这个视图。我将使用模拟表等来保持这一点非常简单。这样我就可以试着理解答案了——不只是复制和粘贴

ICS_用品:

    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;