提问人:stonebe 提问时间:10/18/2023 最后编辑:Thom Astonebe 更新时间:10/18/2023 访问量:48
从 select in while-loop 中获取一个输出表,无需计数
Get one output table from select in while-loop without counting
问:
该表包含: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
- 仅从至少一个数据集
supplier
marker = 1
- 对于哪个小于那个特定的
price
price
marker = 1
supplier
这适用于第 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
答:
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...
观看工作演示
结果:
评论
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;
评论
@Price FLOAT