SQL在限制数据的同时比较2个表

时间:2013-06-27 13:20:19

标签: sql sql-server-2008 select

表格和列名称含糊不清,因为我在医疗行业,无法分享具体细节。我使用此查询显示客户从我公司购买产品(表1)而不是当前供应商(表2)时的节省金额。

我在MSQL Server 2008上有2个这样的表:

Table 1

ProductIDDescriptionVendorPrice


Table 2

ProductIDDescriptionPrice

我想从Table 2中选择每一行以及从Table 1中选择匹配的数据。但我只想从Table 1而不是每个供应商那里以最优惠的价格(供应商中的最低价格)退回供应商。因此,对于ProductID中的任何Table 2Table1应该有一个匹配,如果ProductID中没有匹配的Table 1,则应为NULL值。我在ProductID上加入了表格,并返回了我想要的所有列,但是我无法将其限制为只有表1中的一个结果。如果我在Table 2中使用1000行,我应该返回1000行。我从多个供应商的比赛中得到了一些额外的结果。

结果应如下所示:

T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID,
T2.Description, T2.Price, (T2.Price - T1.Price) as 'Amount Saved'

我写的SQL非常简单:

SELECT 
    T1.ProductID, 
    T1.Description, 
    Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description,
    T2.Price, 
    (T2.Price - T1.Price) AS 'Amount Saved'

FROM 
    Table2 T2 LEFT OUTER JOIN Table1 T1 
        ON T2.ProductID = T1.ProductID
ORDER BY T2.ProductID

D. Stanley的回答有效;稍作修改,选择价格最低的每一行。

SELECT 
    T1.ProductID,
    T1.Description,
    T1.Vendor,
    T1.Price,
    T2.ProductID,
    T2.Description, 
    T2.Price, 
   (T1.Price - T2.Price) as 'Amount Saved'
FROM Table2 T2
LEFT JOIN (
    SELECT * FROM (
       SELECT ProductID, Description, Vendor, Price,
       ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price ASC) AS Row
       FROM Table1) as result
    WHERE row=1
    )  AS T1
    ON T2.ProductID = T1.ProductID

3 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER查找Table1中的“最佳”匹配行:

SELECT 
    T1.ProductID, 
    T1.Description, 
    T1.Vendor, 
    T1.Price, 
    T2.ProductID,
    T2.Description, 
    T2.Price, 
    (T1.Price - T2.Price) as 'Amount Saved'
    FROM Table2 T2
    LEFT JOIN (
        SELECT ProductID, Description, Vendor, Price,
           ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price DESC) Row
           FROM Table1
        ) T1
        ON T2.ProductID = T1.ProductID

答案 1 :(得分:0)

目前尚不清楚,您对“最优价格”的意思是什么。如果它不是您想要的,只需将MAX()函数调整为MIN()函数。

SELECT T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID,
T2.Description, T2.Price, (T1.Price - T2.Price) as 'Amount Saved'
FROM (
SELECT
ProductID, Vendor, Description, Price
FROM Table1 t
WHERE Price = (SELECT MAX(Price) FROM Table1 subT WHERE t.ProductID = subT.ProductID)
) T1 RIGHT JOIN 
Table2 T2 ON T1.ProductID = T2.ProductID
  • Here你应该读些什么。
编辑:我现在读,它是针对SQL Server的。我提供的解决方案和附加的阅读材料也适用于SQL Server。虽然它来自MySQL手册,但只涉及标准的SQL。

答案 2 :(得分:0)

即使我认为有一些更好的预成型查询可能性我喜欢这种方式,如果你想以最低成本包含所有可能性,只需删除外部查询。

如果我对表名不正确,请告诉我这就是我以为你的意思 要求,因为我不是100%确定你的“最佳价格”是什么意思,但我认为它是基于您选择的“已保存金额”字段的最低值。

SELECT
    DISTINCT(T1.ProductId) AS ProductId,
    Description,
    Vendor,
    Price,
    SupplyDescription,
    SupplyPrice,
    AmountSaved AS 'Amount Saved' 
FROM
(
    SELECT 
        T1.ProductId AS ProductId, 
        T1.Description,
        T2.Vendor,
        T1.Price, 
    /*  T2.ProductId you are joining on this no need to include again*/
        T2.Description AS SupplyDescription,
        T2.Price AS SupplyPrice ,
        (T1.Price - ISNULL(T2.Price,T1.Price)) as AmountSaved
    FROM
    Product T1 WITH(NOLOCK)
    LEFT OUTER JOIN Supply T2 WITH(NOLOCK)
        ON T1.ProductId = T2.ProductId
    HAVING T2.Price = MIN(T2.Price)
) tt

注意: 这假设表Product和Supply不是全天动态更新,或者很少更改,如果不是这种情况(产品和供应表经常更新)并且您无法证明通过避免锁定而产生的脏读从查询中删除WITH(NOLOCK)提示