2014-09-30 87 views
0

所以我试图让系统更快。目前我正在轮询数据库数千次以进行一次转换。我正在通过组合数据集/表格来提高速度。 目前我的数据库中有4张桌子:客户,食品交易,饮料交易和沙漠交易。 (这些是占位符名称)。这些设置如下:每个进入客户得到将用于订购的东西从SQL数据库合并和汇总数据

**Customers Table:** 
ID    Customer Name 
0    Harvey 
1    Jessica 
2    Rachel 
3    Louis 
4    Mike 
5    Donna 

**Food Table** 
Transaction ID Food ID Customer ID 
1121   4   1 
1122   2   0 
1125   9   3 
1122   7   0 
1120   6   2 
1122   6   0 

**Drinks Table:** 
Transaction ID Drink ID Customer ID 
1121   2   1 
1121   4   1 
1121   4   1 
1120   3   2 
1125   1   3 
1130   8   4 
1132   8   4 

**Desert Table:** 
Transaction ID Desert ID Customer ID 
1130   1   4 
1125   3   3 
1120   3   2 
2100   9   5 
1118   8   5 
1118   7   5 

现在,我一直在试图JOIN这些表与FULL OUTER结合了唯一的交易号,然而,我认为,我可能会错误地插入此功能。我能够通过使用LEFT JOIN找到相应的客户名称。

没有任何人有任何线索,我怎么可以创建以下表的其余部分:

**Combined Table** 
Transaction IDs  Customer Name  Amount Foods  Amount Drinks  Amount Dessert 
2100    Donna    0    0     1 
1132    Mike    0    1     0 
1130    Mike    0    1     1 
1125    Louis    1    1     1 
1122    Harvey    3    0     0 
1121    Jessica    1    3     0 
1120    Rachel    1    1     1 
1118    Donna    0    0     2 

交易属于一个客户,一个客户然而可以有多个交易编号。因此,由于事务ID在上一个表中是唯一的,所以在使用LEFT JOIN语句时,我不知道您将用作左表。

+0

查询我更新的问题,最终选项卡le和子表不同。问题在于最终表没有原始主表来执行连接功能。那么如何更新查询?我发布了一个新问题,因为我不知道我可以改变这个问题。 – 2014-09-30 22:36:00

回答

0

也许这个查询?

SELECT `Food`.`Customer ID`, `Customers`.`Customer Name`, 
    COUNT(DISTINCT `Food`.`Food ID`) as "Amount Foods", 
    COUNT(DISTINCT `drink`.`Food ID`) as "Amount drinks", 
    COUNT(DISTINCT `desert`.`Food ID`) as "Amount deserts" 
FROM `Food` 
LEFT OUTER JOIN `Customers` ON `food`.`Customer ID` = `Customers`.`ID` 
LEFT OUTER JOIN `Customers` ON `drink`.`Customer ID` = `Customers`.`ID` 
LEFT OUTER JOIN `Customers` ON `desert`.`Customer ID` = `Customers`.`ID` 
GROUP BY `Food`.`Customer ID`, `Customers`.`Customer Name`; 

编辑:

我会建议修改表结构,如果这是可能的。

  • 表1:客户(客户ID,CUSTOMER_NAME,...)
  • 表2:交易(TransactionID的,客户ID,也许日期,时间,...)
  • 表3:订单(订单ID, TransactionID的,类型(1 - 食品,2 - 饮料,3 - 沙漠),日期,时间,...)

然后,你可以这样写

SELECT t.transactionid, c.customername, 
    (SELECT count(*) FROM order food WHERE t.transactionid = food.transactionid and food.type = 1) as food_count, 
    (SELECT count(*) FROM order drink WHERE t.transactionid = drink.transactionid and drink.type = 2) as drink_count, 
    (SELECT count(*) FROM order desert WHERE t.transactionid = desert.transactionid and desert.type = 3) as desert_count 
FROM transaction t 
INNER JOIN customer c on t.customerid = c.customerid 
GROUP BY t.transactionid, c.customername; 
+0

嗨Nebojsa,谢谢你回答这个问题。试图实现它时,我发现我的表格中心点是事务标识,而不一定是名称。名称可以有多个事务ID。但交易ID只能属于一个人。我改变了这个问题。你能帮我解决这个问题吗? – 2014-10-01 08:27:41

+0

@AlexvanRijs你是否有一个事务ID为主键的表? – 2014-10-01 11:01:18

2

这是另一种编写查询的方法。它使用相关子查询,而不是join S IN外部查询:

SELECT c.`Customer ID`, c.`Customer Name`, 
     (select COUNT(DISTINCT f.`Food ID`) from Food f where f.`Customer ID` = c.`ID` 
     ) as "Amount Foods", 
     (select COUNT(DISTINCT d.`Drink ID`) from Drink d where d.`Customer ID` = c.`ID` 
     ) as "Amount Drinks", 
     (select COUNT(DISTINCT d.`Desert ID`) from Desert d where d.`Customer ID` = c.`ID` 
     ) as "Amount Desert", 
FROM Customers c ; 

这做了几件事情:

  • 它阻止笛卡尔积于外水平,当您添加更多的表。
  • 它消除了在外部查询中需要group by
  • 它确保所有客户都在场,即使他们在任何表中都没有行。

注:我保留count(distinct)。但是,你可能不需要它。 count(*)应该是足够的,除非你知道有重复值,你不想数。

+0

嗨戈登,谢谢你的回答。试图实现它时,我发现我的表格中心点是事务标识,而不一定是名称。名称可以有多个事务ID。但交易ID只能属于一个人。我改变了这个问题。你能帮我解决这个问题吗? – 2014-10-01 08:26:46

+0

@AlexvanRijs。 。 。在问题得到解答后,如果新问题使答案无效,那么改变问题实际上是不礼貌的。 – 2014-10-01 11:01:00