1

我正在编写一个存储过程,它将按酒精类别和工作编号显示是/否计数。我开始通过联合对当前的类别(葡萄酒、啤酒、威士忌)进行编程,但提前考虑可能会有更多类别,并且我想象这个代码的大小会越来越大。是否可以在循环中执行联合,然后传递酒精类别参数?在互联网上大肆浏览,在这个主题上看到的很少,所以任何帮助或指导将不胜感激。

我的代码的开始......

delimiter $$
create procedure alc_cat_yn (in jid int)
begin
select
cast(concat(jobid,' - Wine') 
as char(50)) as `Job Number - Consumed Yesterday`
,sum(case when wine_id=1 then 1 else 0 end) as y
,sum(case when wine_id=2 then 1 else 0 end) as n
from demos
where jobid=jid
group by jobid
union all
select
cast(concat(jobid,' - Beer') 
as char(50)) as `Job Number - Consumed Yesterday`
,sum(case when beer_id=1 then 1 else 0 end) as y
,sum(case when beer_id=2 then 1 else 0 end) as n
from demos
where jobid=jid
group by jobid
union all
select
cast(concat(jobid,' - Whisky') 
as char(50)) as `Job Number - Consumed Yesterday`
,sum(case when whisky_id=1 then 1 else 0 end) as y
,sum(case when whisky_id=2 then 1 else 0 end) as n
from demos
where jobid=jid
group by jobid;
end
4

1 回答 1

0

理论上,您可以有一个循环,它在循环中构建查询字符串并将其作为准备好的语句执行。但是,这样做是不好的做法。相反,您应该避免为不同的酒精类别设置不同的列。使用具有多行的单列。每行将包含工作标识、酒精类别和一个值(例如 1 或 2)。

我有点困惑为什么您的列被称为*_id,因为您似乎存储了一些是/否信息,而不是另一个表中某行的标识符。您可能希望选择一个较少误导的名称。

对于类别,您可以使用enum,或存储在字符串中的名称,或引用列出您的种类的其他表的主键的数字。这enum将意味着每个新类别都需要更改数据库模式。字符串可能会消耗大量内存,尤其是在您选择长名称时。因此,对另一个表的引用是最灵活的解决方案,从长远来看可能是您的最佳选择。

您仍然可以基于扩展表将当前结构作为视图提供。如果您为重组表使用新名称,并为此视图重用当前名称,则可以保持与现有代码的向后兼容性。

小提示:MySQL 使用 0 或 1 来表示布尔值。因此,case when foo=bar then 1 else 0 end您可以简单地写而不是写foo=bar。这将使您的代码更短。Otoh,它也会使乍一看更难阅读,所以最好在某处对此用途发表评论。

于 2012-10-18T21:30:28.647 回答