1

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

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

Table 1

ProductID, Description, Vendor,Price


Table 2

ProductID, Description,Price

我想从中选择每一行Table 2并从中选择匹配的数据Table 1。但我只想从 中以最优惠的价格(供应商中最低的价格)退回供应商Table 1,而不是每个供应商。因此,对于任何ProductIDinTable 2都应该有一个匹配 from ,或者如果inTable1没有匹配,则为 NULL 值。我加入了表格并返回了我想要的所有列,但我无法将其限制为表 1 中的一个结果。如果我在 1000 行中执行此操作,我应该返回 1000 行。我不断地从多个供应商匹配中获得一些额外的结果。ProductIDTable 1ProductIDTable 2

结果应如下所示:

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
4

3 回答 3

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
于 2013-06-27T13:37:07.447 回答
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
  • 是您应该阅读的内容。

编辑:我现在读到,它是用于 SQL Server 的。我提供的解决方案和其他阅读材料也适用于 SQL Server。虽然它来自 MySQL 手册,但只涉及标准 SQL。

于 2013-06-27T13:31:43.117 回答
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 不是全天动态更新的,或者很少更改,如果不是这种情况(Product 和 Supply 表经常更新),并且您无法证明避免产生的脏读是合理的锁定只是WITH(NOLOCK)从查询中删除提示

于 2013-06-27T14:03:09.453 回答