从 select in while-loop 中获取一个输出表,无需计数

Get one output table from select in while-loop without counting

提问人:stonebe 提问时间:10/18/2023 最后编辑:Thom Astonebe 更新时间:10/18/2023 访问量:48

问:

该表包含:purchase

row    supplier | type | marker | price
       --------------------------------

1 ....   ABC    |  A   |   0    | 3.50
2 ....   ABC    |  B   |   0    | 4.40
3 ....   ABC    |  B   |   0    | 5.50
4 ....   ABC    |  C   |   1    | 8.70
5 ....   ABC    |  C   |   0    | 9.00

6 ....   DEF    |  A   |   0    | 3.80
7 ....   DEF    |  A   |   0    | 5.10
8 ....   DEF    |  D   |   0    | 9.20

9 ....   GHI    |  E   |   0    | 2.80
10 ...   GHI    |  E   |   0    | 3.30
11 ...   GHI    |  E   |   1    | 4.10
12 ...   GHI    |  E   |   0    | 5.40
13 ...   GHI    |  F   |   0    | 9.90

查询应提供满足以下条件的条目:type

  • 仅从至少一个数据集suppliermarker = 1
  • 对于哪个小于那个特定的pricepricemarker = 1supplier

这适用于第 1、2、3、9 和 10 行。

我的尝试是(遵循 Nakeuri 的一般准则):

DECLARE @supplier CHAR(3), @price FLOAT
DECLARE CurName CURSOR FAST_FORWARD READ_ONLY
FOR
    SELECT SUPPLIER, PRICE
    FROM PURCHASE
    WHERE MARKER = 1
OPEN CurName
FETCH NEXT FROM CurName INTO @supplier, @price
WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT DISTINCT TYPE
        FROM PURCHASE
        WHERE SUPPLIER = @supplier AND PRICE < @price
        FETCH NEXT FROM CurName INTO @supplier, @price
    END
CLOSE CurName
DEALLOCATE CurName

这导致每个供应商的单独输出:

type    (for supplier ABC)
----
 A
 B

type    (for supplier GHI)
----
 E

我需要一个输出表:

type
----
 A
 B
 E

如何编辑查询以将两个输出合并为一个输出?对 Henrik 的建议不能应用,因为我的情况不是计数操作。

系统:

  • 产品:Microsoft SQL Server 标准版(64 位)
  • 操作系统:Windows Server 2022 Standard,版本 21H2
sql-server 选择 while-loop

评论

0赞 Stu 10/18/2023
你为什么要在这里循环,为什么不写一个适当的基于集合的查询?
0赞 Stu 10/18/2023
另外,是 100% 不正确的。@Price FLOAT
0赞 Nick Abbot 10/18/2023
我想教练是在告诉你使用while循环?...但实际上,没有人会这样做。

答:

0赞 Stu 10/18/2023 #1

您需要的基于集的查询(而不是 RBAR 方法)如下所示:

select *
from t
cross apply(
  select Min(price) MinPrice
  from t t2
  where t2.Supplier = t.Supplier and t2.marker = 1
)m
where t.Price < MinPrice;

这将显示已识别的行,您可以从中返回所需的结果

select distinct type from...

观看工作演示

结果:

enter image description here

评论

0赞 Nick Abbot 10/18/2023
为什么不直接批准编辑呢?不同
0赞 Stu 10/18/2023
我认为对 OP 来说,实现识别符合标准的指定行的中间步骤也很有用
0赞 Nick Abbot 10/18/2023
啊,好吧,很公平。OP已经知道这一点。他们在示例中有一个“SELECT DISTINCT TYPE”,并清楚地显示了所需的输出。
0赞 siggemannen 10/18/2023
如果我正确理解了 OP,则每个供应商可能有多行标记 = 1。旧解决方案可能会为每个供应商/行生成多行。我可能也想多了:D
0赞 Nick Abbot 10/18/2023
@siggemannen 我认为 Stu 已经用 min(price) 覆盖了它。获取所有标记的最低价格=1
0赞 Charlieface 10/18/2023 #2

您可以在此处使用窗口功能

SELECT DISTINCT
  t.type
FROM (
    SELECT *,
      MIN(CASE WHEN t.marker = 1 THEN t.price END) OVER
         (PARTITION BY t.supplier) AS MinPrice
    FROM t
) t
WHERE t.Price < t.MinPrice;

db<>fiddle