使用mysql查询从两个表生成账单

时间:2014-01-13 18:07:52

标签: mysql vb6

我在数据库中有一张表,如下所示,

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 " ")将其作为浇头添加到上述项目中。因此,如果要生成账单,如果项目没有任何浇头,那么它们可以像上面的情况一样用芯片加在一起。但是如果物品有浇头,则不应添加与三明治相同的订购物品。

所以请为我提供帮助以生成相同的查询。

2 个答案:

答案 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列,但displaynameqty列会为您提供所需内容。 如果您有多个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;

sqlFiddle

这是一个较短的版本(也有费率和价格)

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;

sqlFiddle