我只是想知道如何用不同的日期到期减去相同产品的数量。
实施例
表广告资源:
Product | Qty | Expiration |
--------+-----+------------+
Oreo | 2 | 10/18/2017 |
Oreo | 6 | 10/09/2017 |
我已请求Inventory
的{{1}}表格,数量为7.那7个奥利奥请求
必须减去首先到期,这是10/09/2017。我的请求剩下1个奥利奥将被减去到下一个到期时间,即10/18/2017所以表格将是这样的
Oreo
答案 0 :(得分:0)
假设:
这是我编写的一个函数,用于演示您需要的逻辑:
// Function to get all the product listing for a given product name in ascending order
public void UpdateProductListing(string myConnString, String productName, Int productQty)
{
MySqlConnection myConnection = new MySqlConnection(myConnString);
MySqlCommand myCommand = (MySqlCommand)myConnection.CreateCommand();
// Warning : never use String query, instead use parametrized query by calling myCommand.Parameters.AddWithValue
myCommand.CommandText = "SELECT Id, Product, Qty, Expiration FROM YourDb.YourTable ORDER BY Expiration ASC";
myConnection.Open();
// The reader enables us to acces each row by calling it's read method
MySqlDataReader myReader = myCommand.ExecuteReader();
try
{
// QtyRemaining variable will hold how much of the quatity is to be taken from next row.
Int QtyRemaining = productQty;
// Always call Read before accessing data.
while (myReader.Read())
{
if (myReader.GetInt16(2) >= productQty)
{
Int NewQty = myReader.GetInt16(2) - productQty;
// At this moment i'm not sure if you need to close the reader before Inserting.
// Anyways you'll require to arrange this code in a proper order to suite your situation
MySqlCommand InsertCommand = (MySqlCommand) myConnection.CreateCommand();
// Warning : never use String query, instead use parametrized query by calling myCommand.Parameters.AddWithValue
InsertCommand.CommandText = "Insert INTO YourDb.YourTable (Qty) VALUES (" + NewQty.toString() + ") WHERE Id=" + myReader.GetInt16(0).toString();
InsertCommand.ExecuteNonQuery();
break;
}
else
{
// Now we know that this particular row cannot supply the entire qty, so we'll set it to zero and move to next row for remaining qty
MySqlCommand InsertCommand = (MySqlCommand) myConnection.CreateCommand();
// Warning : never use String query, instead use parametrized query by calling myCommand.Parameters.AddWithValue
InsertCommand.CommandText = "Insert INTO YourDb.YourTable (Qty) VALUES (" + 0.toString() + ") WHERE Id=" + myReader.GetInt16(0).toString();
InsertCommand.ExecuteNonQuery();
// the quantity to be captured from next row
QtyRemaining = productQty - myReader.GetInt16(2);
}
}
}
finally
{
// always call Close when done reading.
myReader.Close();
// Close the connection when done with it.
myConnection.Close();
}
}
注意:
1.如果您尝试直接编译,此代码可能会出现几个错误。请将其视为逻辑的参考
2.始终使用Paramterized SQL查询。对于.Net MySQL连接器,请参阅:https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-parameters.html
3.您可能需要关闭Reader才能执行查询
4.最好创建一个Product类,然后在那里编写这个逻辑。
希望这会有所帮助。如需进一步查询,请提供您正在尝试的更多详细信息。如果您正在使用.Net桌面应用程序或Web应用程序。如果您使用的是.Net或.Net Core。
答案 1 :(得分:0)
MSSQL版本看起来像这样(再次,很多假设,因为我们无法看到你的表结构实际上是什么样的):
private void SubtractInventory(string product, int qty)
{
string connectionString = "connection sting goes here";
try
{
using (SqlConnection cn = new SqlConnection(connectionString))
{
string sql = $"select ID, PRODUCT, QTY, EXPIRES from PRODUCTS order by EXPIRES asc";
using (SqlDataAdapter adapter = new SqlDataAdapter(sql, cn))
{
using (DataTable tempTable = new DataTable())
{
adapter.Fill(tempTable);
if (tempTable.Rows.Count == 0) throw new Exception("No such product.");
foreach (DataRow r in tempTable.Rows)
{
int newQty = (int)r["QTY"] - qty;
if (newQty >= 0)
{
r["QTY"] = newQty;
qty = 0;
break;
}
else
{
qty = qty - (int)r["QTY"];
r["QTY"] = 0;
}
}
if (qty > 0) throw new Exception($"Not enough of {product} in inventory to subtract {qty}.");
using (SqlCommandBuilder cb = new SqlCommandBuilder(adapter))
{
adapter.UpdateCommand = cb.GetUpdateCommand();
adapter.Update(tempTable);
}
}
}
}
}
catch (Exception ex)
{
// log ex.Message somehow..
}
答案 2 :(得分:0)
您可以使用此查询进行计算。
;WITH CTE AS (
SELECT *,
CumulativeSum= SUM(Qty) OVER (PARTITION BY Product ORDER BY Expiration ROWS UNBOUNDED PRECEDING)
FROM Inventory
)
SELECT Product,
Qty = CASE
WHEN (CumulativeSum - @request) < 0 THEN 0
WHEN (CumulativeSum - @request) BETWEEN 0 AND Qty THEN (CumulativeSum - @request)
ELSE Qty
END
, Expiration
FROM CTE
ORDER BY Product, Expiration
更新表脚本:
;WITH CTE AS (
SELECT *,
CumulativeSum= SUM(Qty) OVER (PARTITION BY Product ORDER BY Expiration ROWS UNBOUNDED PRECEDING)
FROM Inventory
)
UPDATE
CTE
SET
Qty = CASE
WHEN (CumulativeSum - @request) < 0 THEN 0
WHEN (CumulativeSum - @request) BETWEEN 0 AND Qty THEN (CumulativeSum - @request)
ELSE Qty
END
FROM CTE
WHERE CumulativeSum <= Qty + @request