【问题标题】:MySQL query for the logic of three states from two fieldsMySQL从两个字段查询三种状态的逻辑
【发布时间】:2020-12-20 00:57:14
【问题描述】:

我有一个简单的订单,order_items,order_status 架构:

可以看出,order可以有几个order_items。每个 order_item 有两个(布尔)字段,checked_in 和 verify。

订单的状态取值为 ORDERED、RECEIVING、RECEIVED 和 CANCELED。

签入或验证 order_item 后,我想创建一个数据库触发器(在 order_items 表上),为每个 order_item 查询 check_in 和已验证字段的值。

如果未设置任何字段,则订单状态为“已订购”。如果设置了所有字段,则订单状态为“已收到”。如果介于两者之间,则订单状态为“正在接收”。

当前状态设置为“手动”,通过运行以下查询

SELECT oi.checked_in, oi.verified 
FROM order_items AS oi
WHERE order_id = 54;

产生这样的结果:

完整的代码如下所示:

    dsl_shared_ptr<TSQLQuery> q(new TSQLQuery(NULL));
    q->SQLConnection = LITDBConnectionDM->SQLConnection1;

    int orderID = OrdersCDS->FieldByName("id")->AsInteger;

    stringstream query;
    query <<
"\
SELECT oi.checked_in, oi.verified \
FROM order_items AS oi \
WHERE order_id = :oID";
    q->SQL->Add(query.str().c_str());
    q->Params->ParamByName("oID")->AsInteger = orderID;
    q->Open();
    q->First();

    int checkedInCount(0);
    int verifiedCount(0);
    int recordCount(0);
    if(!q->IsEmpty())
    {
        while(!q->Eof)
        {
            recordCount++;
            if(q->FieldByName("checked_in") && q->FieldByName("checked_in")->AsInteger)
            {
                checkedInCount++;
            }

            if(q->FieldByName("verified") && q->FieldByName("verified")->AsInteger)
            {
                verifiedCount++;
            }
            q->Next();
        }
    }

    string orderStatus("");
    if(checkedInCount == 0 && verifiedCount == 0)
    {
        orderStatus = "ORDERED";
    }
    else if(checkedInCount == verifiedCount && checkedInCount == recordCount)
    {
        orderStatus = "RECEIVED";
    }
    else
    {
        orderStatus = "RECEIVING";
    }

    int order_status = getIDForOrderStatus(orderStatus);
    OrdersCDS->Edit();
    OrdersCDS->FieldByName("status")->AsInteger = order_status;
    OrdersCDS->Post();
    OrdersCDS->ApplyUpdates(0);

可以看出,我通过检查每个 order_item 的已验证、checked_in 标志来“手动”推断订单状态。

如何在触发器内的 SQL 查询中实现上述功能?

【问题讨论】:

标签: mysql sql triggers sql-update dbexpress


【解决方案1】:

基本上我认为你要写的update查询是:

update orders o
inner join (
    select 
        order_id, 
        max(checked_in + verified) max_verif, 
        min(checked_in + verified) min_verif
    from order_items AS oi
    where order_id = 54
    group by order_id
) oi on oi.order_id = o.order_id
inner join order_status s on s.status = case
    when max_verif = 0 then 'ORDERED'
    when min_verif = 2 then 'RECEIVED'
    else 'RECEIVING'
end
set o.status = s.id

逻辑是对订单商品进行聚合;我们可以通过查看每个项目的两个状态相加的min()max() 来决定应该为订单分配哪个状态。然后我们带上status表,把状态描述翻译成相关的主键值。

请注意,存储此信息不一定是个好主意。当订单项目的状态发生变化时(或者当新项目添加到订单中,如果您的用例可能的话),需要额外的努力来使信息保持最新。

从上面的查询开始,您可以很好地创建一个视图,它会在查询时即时计算信息。

【讨论】:

  • 我们正在使用这些字段来提醒我们的用户未签入我们库存的 order_items。不确定如何避免这些字段,并且仍然知道与订单关联的 order_item 是否已“签入”?尝试了您的查询,经过一些修改后效果很好!
猜你喜欢
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多