gpt4 book ai didi

sql - 在 SQL 中编写或替换双 for 循环(表遍历另一个表遍历)的有效方法

转载 作者:行者123 更新时间:2023-12-04 03:43:46 25 4
gpt4 key购买 nike

所以现在我有两个表,即 dbo.DEMANDdbo.SUPPLY,其中包含的列包括 bidderID/vendorID , itemID, quantity, bidPrice/sellPrice 等 现在我想定期(完成通过使用 SQL 服务器的代理)和自动匹配满足条件的行(这是我的问题)在下面指定,按publishTime排序,并将一些信息传输到另一个表dbo.DEAL.

我目前的做法是先声明@temp 表,然后将dbo.DEMAND 中的所有内容插入到@temp 中。然后我使用 WHILE 遍历 dbo.DEMAND 表,对于每一行使用 SELECT TOP 1 XXX FROM dbo.SUPPLY 表,当满足特定条件时。最后,当 dbo.SUPPLY 中的遍历完成时,我 DELETE @temp 表中的行(@temp.Quantity 变为 0,或者在 dbo.SUPPLY 表中找不到匹配项时)并从下一个遍历的行重新开始。更具体地说,我的目标是找到所有匹配满足:

{1. @temp.ItemID = SUPPLY.ItemID;
2. @temp.Bid > SUPPLY.Price;
3. @temp.LowestDegre > SUPPLY.DegreeN.}

一个接一个,首先遍历按 DEMAND.PublishTime 排序的 @temp,当找到一个匹配时: p>

{1. For the 2 rows (in the two tables), DELETE both rows and the 1 corresponding row in dbo.DEMAND if Quantities are equal, or, 
DELETE the row with smaller Quantity, and SUBTRACT the Quantity in the row with larger Quantity with the smaller one;
2. Add a row in the DEAL table, containing BuyerID, SellerID, ItemID, BidPrice, etc;
3. Redo the MATCH procedure.}

基本上在我看来,这种方式与 C++ 中的双循环相同。不过听说SQL擅长处理集合(大概就像我们在MATLAB中总是希望矩阵运算一样),逐行遍历确实需要很长时间。如何优化我当前使用的算法?

示例数据: Sample data from the three tables

示例代码:

DECLARE @temp TABLE
(
buyer char(20),
bid float,
quantity smallint,
item char(20),
lowestnew decimal(18,2),
lowestrep decimal(18,2),
pubtime date
);

INSERT INTO @temp(buyer,bid,quantity,item,lowestnew,lowestrep,pubtime)
SELECT BuyerID,Bid,Quantity,ItemID,LowestDegreeNew,LowestReputation,PublishTime FROM DEMAND
ORDER BY PublishTime;
DECLARE @flag int
SET @flag = 0

DECLARE @seller char(20), @buyer CHAR(20), @item char(20), @lowestdegree decimal(18,2), @lowestrep decimal(18,2)

WHILE EXISTS (SELECT buyer, item, lowestnew, lowestrep FROM @temp)

BEGIN

SET @flag = 1

SELECT @buyer = buyer, @item = item, @lowestdegree = lowestnew, @lowestrep = lowestrep FROM @temp

DECLARE @price FLOAT, @quantity SMALLINT

IF EXISTS (select Price, SellerID, Quantity from SUPPLY, SELLER where SellerID = ID and @lowestdegree >= DegreeNew and @lowestrep>=Reputation order by Price)

BEGIN

SELECT TOP 1 @price=Price, @seller = SellerID, @quantity = Quantity FROM SUPPLY, SELLER WHERE SellerID = ID AND @lowestdegree >= DegreeNew AND @lowestrep>=Reputation
IF ((SELECT Quantity FROM DEMAND WHERE SellerID = @seller AND ItemID = @item AND (DegreeNew >= @LowestDegreeNew) AND (Price <= @bid)) IS NOT NULL)
BEGIN /* TRANSFER INTO NEW TABLE */

脚注:我知道这可以很容易地通过在前端编写简单的 C# 或 Python 代码来实现,但我只是想看看是否可以在数据库系统中单独执行此操作。

最佳答案

TLDR:不,您必须继续使用循环结构。

我去过那里。在“最近的一天”加入使得很难使用一个好的集合操作。这就是为什么。考虑那些具有相同等值连接属性的记录(vendor=item 等):

Supply: Day 1
Supply: Day 2
Demand: Day 2

在这种情况下,由于时差,您可能希望将供应日 2 与需求日 2 一起加入。但如果是:

Supply: Day 1 
Supply: Day 2
Demand: Day 2
Demand: Day 3

您可能想要供应第 1 天 - 需求第 2 天和供应第 2 天 - 需求第 3 天。

这意味着每一行都以一种不容易的方式依赖于其他行(即:滞后/超前窗口函数不会救你)。

这是您需要游标/while 的罕见情况之一。

关于sql - 在 SQL 中编写或替换双 for 循环(表遍历另一个表遍历)的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65502827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com