SQL无法弄清楚如何正确连接

时间:2015-01-08 16:24:54

标签: mysql sql sql-server join

有加入问题

我有一个表具有ID和描述列,季节是新的,但描述重复。所以我们可以得到第34季的成人价和第35季的成人价等。

select * from tableA 
-- returns id, description, price, season etc ... 
-- 1 "GT Adult" 10 34
-- 2 "GT Child" 5 34
-- 3 "GT Senior" 8 34 
-- 1 "GT Adult" 11 35
-- 2 "GT Child" 6 35
-- etc. 

TableB有多列,这些列的名称/标题对应于description列。

select * from tableB 
-- returns customer_no adult, child, senior, order_dt, order_data, season, perf_no etc. 
-- returns 112 0, 12, 2, order_dt, order_data, order_season. 
-- returns 415 23, 0, 0, order_dt, order_data, order_season.

基本上每个客户都会为每种类型的门票下订单。 我们可以用来加入的信息是他们匹配的季节和表现......

但我无法弄清楚如何对顾客112说,因为他得到12张儿童票,他应该被收取5张票,而2张高级票他应该被收取8美元的每张票。 如果客户415应该为23张门票中的每一张收取10美元。按季节。

我唯一能做的就是加入赛季,但我如何加入正确的专栏。 请指教。

2 个答案:

答案 0 :(得分:1)

我不认为你可以用你的桌子做你想做的事。没有明确的方法来关联成人" TableB中的列包含" GT Adult"在表A中。

你可以重新设计TableB来解决这个问题:

TableB (customer_no, ticket_type, quantity, order_dt, ...)

因此,对于客户112,我们将在表B中:

112, "GT_Child", 12 ...
112, "GT_Senior", 2 ...

因此,您可以通过加入ticket_type(如果需要,可能还有其他列)来回答您的疑问。

如果可能,您应该将订单本身的详细信息移到第三个表格中(让我们称之为TableC)并分配订单号。因此,我们现在拥有TableA,然后:

TableB (order_no, customer_no, ticket_type, quantity)
TableC (order_no, order_dt, season ...)

答案 1 :(得分:0)

您可以使用PIVOT以每季单行获取所有门票价格

SELECT season, [GT Adult], [GT Child], [GT Senior]
FROM (
   SELECT season, price, [description]
   FROM tableA
   ) source
   PIVOT (
      MAX(price)
      FOR [description] IN ([GT Adult], [GT Child], [GT Senior])
   ) pvt

鉴于OP中引用的样本数据,上面产生的结果如下:

season  GT Adult    GT Child    GT Senior
-----------------------------------------
34      10          5           8
35      11          6           NULL

然后,您可以执行简单的INNER JOIN操作,以获取每个客户订单的总金额:

SELECT customer_no, adult * [GT Adult] + child *  [GT Child] + senior * [GT Senior] AS total
FROM tableB AS B
INNER JOIN ( 
   SELECT season, [GT Adult], [GT Child], [GT Senior]
   FROM (
      SELECT season, price, [description]
      FROM tableA) source
      PIVOT (
         MAX(price)
         FOR [description] IN ([GT Adult], [GT Child], [GT Senior])
      ) pvt
) t ON b.season = t.season

SQL Fiddle Demo

P.S。以上查询适用于SQL Server。

编辑:

要在PIVOT中模拟MySQL,我们必须使用条件聚合:

select season,
       sum(if(description='GT Adult', price ,null)) as adultPrice,
       sum(if(description='GT Child', price ,null)) as childPrice,
       sum(if(description='GT Senior', price ,null)) as seniorPrice
from tableA 
group by season;

以上查询为我们提供了可以执行JOIN操作的结果集:

SELECT customer_no, adult * adultPrice + child *  childPrice + senior * seniorPrice AS total
FROM tableB AS b
INNER JOIN ( 
  SELECT season,
       SUM(IF(description='GT Adult', price ,null)) AS adultPrice,
       SUM(IF(description='GT Child', price ,null)) AS childPrice,
       SUM(IF(description='GT Senior', price ,null)) AS seniorPrice
  FROM tableA 
  GROUP BY season) AS a ON b.season = a.season

MySQL Demo here