You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询不含FiredAlways炉灶的发票中总价第二低的记录

解决未销售FiredAlways炉灶发票中总价第二低的问题

看起来你现在卡在了如何从未包含FiredAlways类型炉灶的发票里拿到总价第二低的记录,我来帮你调整SQL代码,提供几种可行的方案:

先明确核心逻辑:筛选符合条件的发票

首先要确保我们筛选的发票是完全没有销售FiredAlways炉灶的,原来的EXISTS子查询逻辑可能有问题,正确的筛选应该是:

SELECT I.InvoiceNbr, I.InvoiceDt, I.TotalPrice
FROM INVOICE I
WHERE NOT EXISTS (
    -- 检查该发票是否存在任何FiredAlways类型的炉灶行项
    SELECT 1
    FROM INV_LINE_ITEM li
    JOIN STOVE s ON li.FK_StoveNbr = s.SerialNumber
    WHERE li.FK_InvoiceNbr = I.InvoiceNbr
      AND s.Type = 'FiredAlways'
)

这段代码会先过滤出所有从未卖过FiredAlways炉灶的发票,接下来在此基础上获取第二低的总价记录。


方案1:使用OFFSET-FETCH(SQL Server 2012+ 推荐)

这是最简洁直观的方式,先按总价升序排序,跳过第1条(最低的),然后取第1条就是第二低的:

SELECT I.InvoiceNbr, I.InvoiceDt, I.TotalPrice
FROM INVOICE I
WHERE NOT EXISTS (
    SELECT 1
    FROM INV_LINE_ITEM li
    JOIN STOVE s ON li.FK_StoveNbr = s.SerialNumber
    WHERE li.FK_InvoiceNbr = I.InvoiceNbr
      AND s.Type = 'FiredAlways'
)
ORDER BY I.TotalPrice ASC
OFFSET 1 ROW FETCH NEXT 1 ROW ONLY;

如果有多个发票总价相同且都是第二低的(比如最低是100,有两个150的),这个方法只会返回其中一条;如果想返回所有并列第二低的,把FETCH NEXT 1 ROW ONLY改成FETCH NEXT 0 ROWS WITH TIES即可。


方案2:排除最低总价后取最低(兼容旧版SQL Server)

如果你的SQL Server版本低于2012,不支持OFFSET,可以用这个方法:先找到符合条件的发票中的最低总价,然后筛选出总价大于这个值的发票,再取其中最低的,也就是第二低的:

SELECT TOP 1 I.InvoiceNbr, I.InvoiceDt, I.TotalPrice
FROM INVOICE I
WHERE NOT EXISTS (
    SELECT 1
    FROM INV_LINE_ITEM li
    JOIN STOVE s ON li.FK_StoveNbr = s.SerialNumber
    WHERE li.FK_InvoiceNbr = I.InvoiceNbr
      AND s.Type = 'FiredAlways'
)
AND I.TotalPrice > (
    -- 先获取符合条件的发票中的最低总价
    SELECT MIN(TotalPrice)
    FROM INVOICE I2
    WHERE NOT EXISTS (
        SELECT 1
        FROM INV_LINE_ITEM li2
        JOIN STOVE s2 ON li2.FK_StoveNbr = s2.SerialNumber
        WHERE li2.FK_InvoiceNbr = I2.InvoiceNbr
          AND s2.Type = 'FiredAlways'
    )
)
ORDER BY I.TotalPrice ASC;

同样,如果要返回所有并列第二低的,把TOP 1改成TOP 1 WITH TIES。


方案3:使用窗口函数(灵活处理排名)

用DENSE_RANK()或者ROW_NUMBER()窗口函数来给符合条件的发票按总价排名,然后取排名为2的记录:

WITH RankedInvoices AS (
    SELECT 
        I.InvoiceNbr, 
        I.InvoiceDt, 
        I.TotalPrice,
        -- 用DENSE_RANK会把相同总价的发票排同一名,ROW_NUMBER则每个发票唯一排名
        DENSE_RANK() OVER (ORDER BY I.TotalPrice ASC) AS PriceRank
    FROM INVOICE I
    WHERE NOT EXISTS (
        SELECT 1
        FROM INV_LINE_ITEM li
        JOIN STOVE s ON li.FK_StoveNbr = s.SerialNumber
        WHERE li.FK_InvoiceNbr = I.InvoiceNbr
          AND s.Type = 'FiredAlways'
    )
)
SELECT InvoiceNbr, InvoiceDt, TotalPrice
FROM RankedInvoices
WHERE PriceRank = 2;
  • 如果用ROW_NUMBER():即使有多个发票总价相同,每个都会有不同的排名,只会返回其中一条;
  • 如果用DENSE_RANK():所有总价相同的第二低发票都会被返回,适合需要并列结果的场景。

注意点

  • 请确保你的表之间的关联字段(FK_InvoiceNbr、FK_StoveNbr、SerialNumber)是正确关联的,避免数据筛选错误;
  • 如果符合条件的发票数量少于2条,这些查询会返回空结果,你可以根据业务需求添加处理逻辑。

内容的提问来源于stack exchange,提问作者rgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:37:06