【问题标题】:Select the cheapest price and then group it by the vendor?选择最便宜的价格,然后按供应商分组?
【发布时间】:2019-11-11 22:51:07
【问题描述】:

我想为技术采购团队提供默认供应商设置,让他们知道在哪里订购零件。这是基于一个名为 price_book 的表。为此,我需要一个新表,其中包含零件号、最便宜的价格和供应商代码,以通过系统处理它。如何只选择价格最低的供应商?

我这样做是为了简化技术采购团队的订购流程。到目前为止,我只有每个供应商最便宜的价格(关于最低订购量)。我缺少的是只选择了一个价格最便宜的供应商的部分。所以每个零件编号与相应供应商的最便宜的价格。

查询很短:

SELECT DISTINCT pb.partno, MIN(pb.purch_price * c.rate) AS 'cheapest_price', pb.supplier
FROM price_book pb
LEFT JOIN currency c ON c.currency = pb.currency
WHERE pb.contract_id <> 0
AND pb.expire_date > Datediff(Day, '31 Dec 1971', Getdate())
AND pb.order_type = 'P'
AND pb.condition = 'N'
GROUP BY partno, supplier

WHERE 子句并不重要,因为它与内部流程有关。

结果应该是一个包含部件号、价格和相应供应商列的列表。每个零件编号应该只有供应商最便宜的价格。

【问题讨论】:

  • 查询中有任何 SELECT 吗?
  • 哦,对不起!刚刚添加了 SELECT 语句

标签: sql tsql sybase


【解决方案1】:

我现在找到了适合我的代码:

SELECT B.partno,
MAX(C.supplier) AS supplier
FROM

(SELECT A.partno,
MIN(A.price) AS price
FROM

(SELECT DISTINCT pb.partno AS partno, MIN(pb.purch_price * c.rate) AS price, pb.supplier AS supplier
FROM price_book pb
LEFT JOIN currency c ON c.currency = pb.currency
LEFT JOIN part p ON p.partno = pb.partno
WHERE pb.contract_id <> 0
AND pb.expire_date > Datediff(Day, '31 Dec 1971', Getdate())
AND pb.order_type = 'P'
AND pb.condition = 'N'
AND p.mat_class IN ('C', 'E')
GROUP BY pb.partno, supplier) A

GROUP BY A.partno) B

JOIN (SELECT DISTINCT pb.partno AS partno, MIN(pb.purch_price * c.rate) AS price, pb.supplier AS supplier
FROM price_book pb
LEFT JOIN currency c ON c.currency = pb.currency
LEFT JOIN part p ON p.partno = pb.partno
WHERE pb.contract_id <> 0
AND pb.expire_date > Datediff(Day, '31 Dec 1971', Getdate())
AND pb.order_type = 'P'
AND pb.condition = 'N'
AND p.mat_class IN ('E', 'C')
GROUP BY pb.partno, supplier) C ON B.partno=C.partno and B.price=C.price
GROUP BY B.partno

非常感谢你们给我的支持!!

干杯, 多米尼克

【讨论】:

    【解决方案2】:

    看看:

    DECLARE @priceBook TABLE (PriceID       INT IDENTITY(1, 1)
    ,                         PartNo        NVARCHAR(10)
    ,                         Price         DECIMAL(18, 2)
    ,                         fk_SupplierID INT);
    
    INSERT INTO @priceBook (PartNo, Price, fk_SupplierID)
    VALUES (N'123', 8.99, 1)
    ,      (N'123', 9.99, 2)
    ,      (N'456', 10.99, 1)
    ,      (N'456', 3.99, 2)
    ,      (N'456', 12.99, 3);
    
    WITH cte AS
        (SELECT PriceID
         ,      PartNo
         ,      Price
         ,      fk_SupplierID
         ,      ROW_NUMBER() OVER (PARTITION BY PartNo
    ORDER BY Price ASC) RN
           FROM @priceBook)
    SELECT  cte.PriceID
    ,       cte.PartNo
    ,       cte.Price
    ,       cte.fk_SupplierID
      FROM  cte
     WHERE  rn = 1;
    

    这是上面提到的窗口功能的一个基本示例。这确实在 MS SQL Server 上运行,不确定 mySQL。给它一个测试,如果它对你有用,那么你可以根据你的确切结构进行调整。

    【讨论】:

    • 这里我收到一条错误消息,提示“批处理必须以选择/更新/插入/删除命令开头”
    • 能否确认您使用的是 mySQL 还是 MS SQL Server?
    • 系统管理员说我们使用的是T-SQL
    • T-SQL 是语言——我们正在寻找的是服务器类型。 T-SQL 暗示 Microsoft SQL Server,但您的错误消息暗示了其他内容。
    • 我不确定这是否是您正在寻找的答案,但它是 SYBASE DBMS 15.7 吗?
    【解决方案3】:

    你可以试试windows函数,代码类似于下面的例子

    注意 - 代码未经测试。

    SELECT * from
    (SELECT pb.partno,pb.supplier,pb.purch_price * c.rate as price, 
    row_number() over(partition by pb.partno,pb.supplier order by pb.purch_price * c.rate )rn
    FROM price_book pb
    LEFT JOIN currency c ON c.currency = pb.currency
    WHERE pb.contract_id <> 0
    AND pb.expire_date > Datediff(Day, '31 Dec 1971', Getdate())
    AND pb.order_type = 'P'
    AND pb.condition = 'N')a
    where a.rn=1
    

    【讨论】:

    • My SQL server 无法识别 OVER 语句。弹出的消息是“关键字'over'附近的语法不正确”
    • 你是说 MSSQL?
    • 我们在公司使用 T-SQL。而且它不是在 Windows 应用程序中,而是在一个非常具体的航空软件中。
    • TSQL,支持over子句。
    • 你的错误信息是MY SQL,所以你提到的服务器是错误的,你没有使用TSQL你正在使用My SQL。据我所知,我的 SQL 没有 over 子句。您应该将相关标签更改为 My SQL
    【解决方案4】:

    试试TOP(1) WITH TIES

    SELECT TOP(1) WITH TIES pb.partno, pb.purch_price * c.rate [cheapest_price], pb.supplier
    FROM price_book pb
    LEFT JOIN currency c ON c.currency = pb.currency
    WHERE pb.contract_id <> 0
    AND pb.expire_date > Datediff(Day, '31 Dec 1971', Getdate())
    AND pb.order_type = 'P'
    AND pb.condition = 'N'
    ORDER BY row_number() over(partition by partno order by pb.purch_price * c.rate [cheapest_price] desc);
    

    【讨论】:

    • T-SQL 服务器无法识别 WITH TIES 语句。弹出的消息是“关键字'WITH'附近的语法不正确”
    • @domonic.landert ,正确标记 dbms。此答案适用于 ms sql server 当前支持的版本。
    • 我询问了负责的系统,他向我保证是 T-SQL。
    • docs.microsoft.com/en-us/sql/t-sql/queries/… TOP(1) WITH TIES 自 2008 年起受支持。您的版本是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2016-05-28
    • 2016-03-18
    • 2020-08-03
    相关资源
    最近更新 更多