Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.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_Sql Server_Left Join - Fatal编程技术网

带有连接的复杂SQL视图&;Where子句

带有连接的复杂SQL视图&;Where子句,sql,sql-server,left-join,Sql,Sql Server,Left Join,我的SQL技能水平相当基本。我当然写了一些一般性的查询,并做了一些非常一般的视图。但是,一旦我们进入连接,我就窒息了,无法得到我想要的结果,在我正在创建的视图中 我感觉我就快到了。就是拿不到最后一块 SELECT dbo.ics_supplies.supplies_id, dbo.ics_supplies.old_itemid, dbo.ics_supplies.itemdescription, dbo.ics_supplies.onhand,

我的SQL技能水平相当基本。我当然写了一些一般性的查询,并做了一些非常一般的视图。但是,一旦我们进入连接,我就窒息了,无法得到我想要的结果,在我正在创建的视图中

我感觉我就快到了。就是拿不到最后一块

SELECT dbo.ics_supplies.supplies_id,
       dbo.ics_supplies.old_itemid,
       dbo.ics_supplies.itemdescription,
       dbo.ics_supplies.onhand,
       dbo.ics_supplies.reorderlevel,
       dbo.ics_supplies.reorderamt,
       dbo.ics_supplies.unitmeasure,
       dbo.ics_supplies.supplylocation,
       dbo.ics_supplies.invtype,
       dbo.ics_supplies.discontinued,
       dbo.ics_supplies.supply,
       dbo.ics_transactions.requsitionnumber,
       dbo.ics_transactions.openclosed,
       dbo.ics_transactions.transtype,
       dbo.ics_transactions.originaldate
FROM   dbo.ics_supplies
       LEFT OUTER JOIN dbo.ics_orders
                    ON dbo.ics_supplies.supplies_id = dbo.ics_orders.suppliesid
       LEFT OUTER JOIN dbo.ics_transactions
                    ON dbo.ics_orders.requisitionnumber =
                       dbo.ics_transactions.requsitionnumber
WHERE  ( dbo.ics_transactions.transtype = 'PO' ) 
当我不包含WHERE子句时,我的视图中有17000多条记录。这是不对的。这样做是因为我们在一个1对多的表上进行匹配。供应表是12000条记录。应该总是有12000条记录。再也不会了。从来没有少过

我缺少的是:

  • 我只需要ICS_Transactions表中的一条匹配记录。理想情况下,我想要的是最新的“ICS_Transactions.OriginalDate”

  • 如果ICS_Transacions.Type='PO',我只希望填充ICS_Transacions表字段。否则,这些字段应保持为空

  • 示例代码或任何东西都会很有帮助。我已经做了很多关于连接的研究,但要得到我需要的结果仍然很混乱

    编辑/更新

    我觉得好像我问错了我的问题,或者对我所问的问题没有给出一个很好的整体看法。为此,我道歉。我对SQL还是很陌生,但我正在努力

    ICS_Supplies表有12810条记录 ICS_订单表有3666条记录 ICS_事务表有4701条记录

    简而言之,我希望看到12810条记录的结果。不多也不少。我正在尝试创建ICS_Supplies表中所有记录的视图

    并非供货表中的所有记录都在订单和/或交易表中。但无论如何,我还是想看到所有12810条记录

    我的用户要求,如果这些供应品中的任何一个有一个打开的PO(ICS_Transactions.OpenClosed='open'和ICS_Transactions.InvType='PO'),那么我还希望看到ICS_Transactions中的其他字段(ICS_Transactions.OpenClosed、ICS_Transactions.InvType、ICS_Transactions.OriginalDate、ICS_Transactions.RequsionNumber)

    如果供应记录没有打开的采购订单,则这些附加字段应为空/空(无论这些添加的字段中有什么数据,如果不符合条件,则应显示空)

    ICS_Orders表只需从ICS_供应品跳到ICS_交易(我首先需要从Orders字段获取申请编号,如果有)


    如果我没有很好地解释这一点,我很抱歉。请询问您是否需要澄清。

    您可以使用下面的查询获得您需要的信息

    一,。我只需要ICS_Transactions表中的一条匹配记录。理想情况下,我想要的是最新的“ICS_Transactions.OriginalDate”

    我将通过创建一个CTE来解决这个问题,该CTE包含查询中所需的所有ICS_事务字段,按OPriginalDate排序,按suppliesid分区

    二,。如果ICS_Transacions.Type='PO',我只希望填充ICS_Transacions表字段。否则,这些字段应保持为空

    如果将条件从WHERE子句移动到左联接,则不符合条件的ICS_事务将被剥离,并用null值替换为其余的查询记录

    ;
    WITH ReqNumberRanked AS
    (
        SELECT
            dbo.ICS_Orders.SuppliesID,
            dbo.ICS_Transactions.RequisitionNumber,
            dbo.ICS_Transactions.TransType,
            dbo.ICS_Transactions.OriginalDate,
            dbo.ICS_Transactions.OpenClosed, 
            RequisitionNumberRankReversed = RANK() OVER(PARTITION BY dbo.ICS_Orders.SuppliesID, dbo.ICS_Transactions.RequisitionNumber ORDER BY dbo.ICS_Transactions.OriginalDate DESC)  
        FROM
            dbo.ICS_Orders
            LEFT OUTER JOIN dbo.ICS_Transactions ON dbo.ICS_Orders.RequisitionNumber = dbo.ICS_Transactions.RequsitionNumber
    )
    SELECT        
        dbo.ICS_Supplies.Supplies_ID, dbo.ICS_Supplies.Old_ItemID, 
        dbo.ICS_Supplies.ItemDescription, dbo.ICS_Supplies.OnHand, 
        dbo.ICS_Supplies.ReorderLevel, dbo.ICS_Supplies.ReorderAmt, 
        dbo.ICS_Supplies.UnitMeasure, 
        dbo.ICS_Supplies.SupplyLocation, dbo.ICS_Supplies.InvType, 
        dbo.ICS_Supplies.Discontinued, dbo.ICS_Supplies.Supply, 
        ReqNumberRanked.RequsitionNumber, 
        ReqNumberRanked.OpenClosed, 
        ReqNumberRanked.TransType, 
        ReqNumberRanked.OriginalDate
    FROM            
        dbo.ICS_Supplies 
        LEFT OUTER JOIN dbo.ICS_Orders ON dbo.ICS_Supplies.Supplies_ID = dbo.ICS_Orders.SuppliesID 
        LEFT OUTER JOIN ReqNumberRanked ON ReqNumberRanked.RequisitionNumber = dbo.ICS_Transactions.RequsitionNumber 
            AND (ReqNumberRanked.TransType = 'PO') 
            AND ReqNumberRanked.RequisitionNumberRankReversed = 1
        
    

    下面是罗斯·布什答案的简化版本(它从CTE中删除了一个连接,以使事情更加集中,加快速度,并减少代码)

    这将仅加入每个
    requisionnumber
    的最新交易记录,并且仅当其具有
    transtype='PO'


    如果您想反转该值(只加入具有
    transtype='PO'
    的交易记录,并且只加入最近的交易记录),然后将
    transtype='PO'
    过滤器移动到
    ordered\u ics\u事务中的
    WHERE
    子句中。

    WHERE子句条件使左连接返回常规的内部连接结果。如果希望得到真正的左连接结果,请将其移动到ON子句。我尝试过这样做:左外部连接dbo.ics_transactions.requisionnumber=dbo.ics_orders.requisionnumber和dbo.ics_transactions.traanstype='PO',但仍然会返回17k+条记录。ics_Transaction表中的主键是什么?我假设有一个自动递增的“ID”列。此外,是否可以假定交易日期将遵循添加到表中的项目的自然顺序?ie:你不会有一个日期在10/2之后的ID=1234和日期在9/27之后的ID 1235。它们将按照添加日期的自然顺序排列ID?@drapp从不以这种方式使用代理密钥。虽然通常的行为是按顺序分配,但不能保证这种行为。更不用说人的因素了;标识插入、主键值更新等。始终使用datetime列来建立datetime顺序。@MatBailie,我同意,但没有看到最终的表结构,知道添加的任何日期/时间与此类订单日期的上下文,在这种情况下,我将依赖自动递增。再一次,我只是缺少完整的信息范围。我以前从未使用过分区,因此我没有太多的洞察力。我得到以下错误:函数参数列表中的错误:“分区”未被识别。无法分析查询文本。Doh!那是因为我打错了字。已经修好了。语法是RANK()OVER(ORDER BY Y)。RANK中的分区指定排名的集群或分组,在您的例子中,我认为这是供应商,然后是请购编号。这意味着对于每个供应商,请购单编号将按照“订单依据”字段中指定的顺序排列,原始日期似乎是一个很好的候选日期。这将允许重复的供应商/申请编号参与排名。由于这些值的顺序是相反的,每个分区的第一条记录将是供应商和require的最后一条现有记录
    ;WITH
      ordered_ics_transactions AS
    (
      SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY requisitionnumber
                               ORDER BY originaldate DESC
                          )
                            AS seq_id
      FROM
        dbo.ics_transactions
    )
    SELECT
      s.supplies_id,      s.old_itemid,
      s.itemdescription,  s.onhand,
      s.reorderlevel,     s.reorderamt,
      s.unitmeasure,      s.supplylocation,
      s.invtype,          s.discontinued,
      s.supply,
      t.requsitionnumber, t.openclosed,
      t.transtype,        t.originaldate
    FROM
      dbo.ics_supplies           AS s
    LEFT OUTER JOIN
      dbo.ics_orders             AS o
        ON  o.supplies_id = s.suppliesid
    LEFT OUTER JOIN
      ordered_ics_transactions   AS t
        ON  t.requisitionnumber = o.requisitionnumber
        AND t.transtype         = 'PO'
        AND t.seq_id            = 1