我在数据库中有一张表,如下所示,
menugroups :
+----Name---+--PrintOdr-+
+-----------+-----------+
|Starters |1 |
|Deserts |2 |
|Soups |3 |
+-----------+-----------+
另外一张表如下,
订单
+----ID-----+---Name----+--MenuGrp--+TableNo+
+-----------+-----------+-----------+-------+
|1 |Sandwich |Starters |1 |
|"space" |Cheese |Starters |1 |
|2 |Chips |Starters |1 |
|3 |Brownie |Deserts |1 |
|"space" |IceCream |Deserts |1 |
|1 |Sandwich |Starters |1 |
|2 |Chips |Starters |1 |
+-----------+-----------+-----------+-------+
现在我希望将帐单生成为,
tablenos :
+----Name---+--Qty--+
+-----------+-------+
|Sandwich |1 |
|Cheese |1 |
|Chips |2 |
|Sandwich |1 |
|Brownie |1 |
|Icecream |1 |
+-----------+-------+
PrintOdr
中的 menugroups
给出了订购商品的订单。
因此,根据上面定义的menugroups
,应首先打印初学者,然后打印沙漠,然后打印汤。 menugroups
也可以有相同的PrintOdr
,表示可以按任意顺序打印。在orders
项中,ID="Space" (means " ")
将其作为浇头添加到上述项目中。因此,如果要生成账单,如果项目没有任何浇头,那么它们可以像上面的情况一样用芯片加在一起。但是如果物品有浇头,则不应添加与三明治相同的订购物品。
所以请为我提供帮助以生成相同的查询。
答案 0 :(得分:0)
试试这个,如果你将menugroup id放在订单的MenuGrp列中,那么你可以根据名称和MenuGrps加入表格,这会更好地相关
SELECT
o.`name`,
COUNT(o.`name`) AS qty
FROM
orders o
JOIN menugroups m
ON (m.`name` = o.MenuGrp)
GROUP BY o.`name`
ORDER BY m.PrintOdr ASC
答案 1 :(得分:0)
顶部它是如此棘手,很多玩变量,但这里是一个查询,给你你想要的。基本上我会使用变量来生成不同的ID(如果某个项目有多项权限。
)SELECT IF(IsTopping, CONCAT("+",t3.Name),t3.Name) as DisplayName,
Count(*) as Qty,
IF(HasTopping,CONCAT(t3.Name,GeneratedId),
IF(isTopping,CONCAT(t3.Name,GeneratedId),CONCAT(t3.Name,ID))) as newName
FROM
(
SELECT *,IF (EXISTS (SELECT 1 FROM
(select *,IF (@prevNewId2 != newId,@generatedID2:=@generatedID2 + 1,@generatedID2) as generatedID,
@prevNewId2 := NewId
from
(select *,IF (ID = ' ',@prevID2,ID) as newID,
IF (ID != ' ',@prevID2 := ID,@prevID2),
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @prevID2 := 0)var)o,(SELECT @prevNewId2:=0,@generatedID2 := 1000)var
)t2
WHERE t2.generatedID = t1.generatedID
AND t2.isTopping = 1
) AND isTopping = 0,1,0) as hasTopping
FROM
(select *,IF (@prevNewId != newId,@generatedID:=@generatedID + 1,@generatedID) as generatedID,
@prevNewId := NewId
from
(select *,IF (ID = ' ',@prevID,ID) as newID,
IF (ID != ' ',@prevID := ID,@prevID),
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @prevID := 0)var)o,(SELECT @prevNewId:=0,@generatedID := 1000)var
)t1
)t3 INNER JOIN menugroups mg ON mg.Name = t3.MenuGrp
GROUP BY DisplayName,NewName
ORDER BY mg.PrintOdr,t3.generatedID,t3.isTopping
请参阅sqlFiddle,您可以忽略它仅用于分组的newname
列,但displayname
和qty
列会为您提供所需内容。
如果您有多个TableNo,则可能必须在WHERE TableNo = 1
选择时添加orders
。
第二个版本查询解决问题,其中1个三明治是在没有打顶的情况下在另一个三明治之后打顶。
SELECT IF(IsTopping, CONCAT("+",t3.Name),t3.Name) as DisplayName,
Count(*) as Qty,
IF(HasTopping,CONCAT(t3.Name,GeneratedId),
IF(isTopping,CONCAT(t3.Name,GeneratedId),CONCAT(t3.Name,ID))) as newName
FROM
(
SELECT *,IF (EXISTS (SELECT 1 FROM
(select *,IF (@prevNewId2 != newId,@generatedID2:=@generatedID2 + 1,@generatedID2) as generatedID,
@prevNewId2 := NewId
from
(select *,IF (ID = ' ',@prevID2,@newId2:=@newId2+1) as newID,
IF (ID != ' ',@prevID2 := @newId2,@prevID2),
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @prevID2 := 0,@newId2:=0)var
)o,(SELECT @prevNewId2:=0,@generatedID2 := 1000)var
)t2
WHERE t2.generatedID = t1.generatedID
AND t2.isTopping = 1
) AND isTopping = 0,1,0) as hasTopping
FROM
(select *,IF (@prevNewId != newId,@generatedID:=@generatedID + 1,@generatedID) as generatedID,
@prevNewId := NewId
from
(select *,IF (ID = ' ',@prevID,@newId:=@newId+1) as newID,
IF (ID != ' ',@prevID := @newId,@prevID),
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @prevID := 0,@newId:=0)var
)o,(SELECT @prevNewId:=0,@generatedID := 1000)var
)t1
)t3 INNER JOIN menugroups mg ON mg.Name = t3.MenuGrp
GROUP BY DisplayName,NewName
ORDER BY mg.PrintOdr,t3.generatedID,t3.isTopping;
这是一个较短的版本(也有费率和价格)
SELECT IF(IsTopping, CONCAT("+",t3.Name),t3.Name) as DisplayName,
Count(*) as Qty,
t3.rate,t3.rate * Count(*) as price,
IF(HasTopping,CONCAT(t3.Name,newId),
IF(isTopping,CONCAT(t3.Name,newId),CONCAT(t3.Name,ID))) as newName
FROM
(SELECT *,IF (EXISTS (SELECT 1 FROM
(select *,IF (ID = ' ',@newId2,@newId2:=@newId2+1) as newID,
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @newId2:=1000)var
)t2
WHERE t2.newId = t1.newId
AND t2.isTopping = 1
) AND isTopping = 0,1,0
) as hasTopping
FROM (select *,IF (ID = ' ',@newId,@newId:=@newId+1) as newID,
IF (ID = ' ',1,0) as isTopping
from orders,(SELECT @newId:=1000)var
)t1
)t3 INNER JOIN menugroups mg ON mg.Name = t3.MenuGrp
GROUP BY DisplayName,NewName,rate
ORDER BY mg.PrintOdr,t3.newId,t3.isTopping;