带有连接的复杂SQL视图&;Where子句
我的SQL技能水平相当基本。我当然写了一些一般性的查询,并做了一些非常一般的视图。但是,一旦我们进入连接,我就窒息了,无法得到我想要的结果,在我正在创建的视图中 我感觉我就快到了。就是拿不到最后一块带有连接的复杂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,
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” 我将通过创建一个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