MySQL从两个字段中查询三种状态的逻辑

问题描述

我有一个简单的订单,order_items,order_status模式:

enter image description here

可以看出,订单可以有多个order_items。每个order_item具有两个(布尔值)字段,checked_in和validated。

订单的状态为“已订购”,“已接收”,“已接收”和“已取消”值。

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

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

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

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

产生如下结果:

enter image description here

完整代码如下:

    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查询中实现以上目标?

解决方法

基本上,我认为您要编写的library(tidyverse) #Data dfa <- structure(list(id_item = c(60L,9L,31L,25L,76L,48L),test_label = c(2L,5L,4L,12L,2L),xgb_1 = c(2L,8L,6L,2L,4L)),class = "data.frame",row.names = c("2","7","12","21","31","36")) 查询是:

#Reshape
dfa %>% pivot_longer(cols = -id_item) %>%
  ggplot(aes(x=value,fill=name))+
  geom_histogram(position = position_dodge())+
  facet_wrap(.~id_item)

逻辑是汇总订单项目;我们可以通过查看每个项目两个状态的相加的updateupdate 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()表将状态描述转换为相关的主键值。

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

从上述查询开始,您可以很好地创建一个 view ,该视图可以在查询时即时计算信息。