【问题标题】:SQL Comparing 2 tables while limiting dataSQL比较2个表同时限制数据
【发布时间】:2013-06-27 13:20:19
【问题描述】:

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

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

Table 1

ProductIDDescriptionVendorPrice


Table 2

ProductIDDescriptionPrice

我想从Table 2 中选择每一行,并从Table 1 中选择匹配数据。但是我只想从Table 1返回价格最优惠(供应商中价格最低)的供应商,而不是每个供应商。因此,对于Table 2 中的任何ProductID,应该有一个来自Table1 的匹配项,或者如果在Table 1 中没有匹配的ProductID,则为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

【问题讨论】:

  • 您可以发布查询吗?
  • 什么是“最佳价格”,您的意思是最低(最低)价格、最高节省等?请粘贴您尝试过的代码

标签: sql sql-server-2008 select


【解决方案1】:

您可以使用ROW_NUMBERTable1 中找到“最佳”匹配行:

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

【讨论】:

    【解决方案2】:

    不清楚,您所说的“最优价格”是什么意思。如果不是您想要的,只需将 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。

    【讨论】:

      【解决方案3】:

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

      如果我对表名有误,请告诉我这是我假设的 询问是因为我不是 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) 提示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-25
        • 1970-01-01
        • 2013-07-20
        • 2011-11-22
        相关资源
        最近更新 更多