SQL不知道如何正确加入
SQL can't figure out how to join correctly
加入问题
我有一个 table 有一个 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 有多个列,这些列有 names/headers 对应于描述列。
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 美元。按季节。
我唯一能确定的就是加入赛季,但我如何加入正确的列。
请指教。
我不认为你可以用你拥有的 table 做你想做的事。没有明确的方法将表 B 中的 "adult" 列与表 A 中包含 "GT Adult" 的行相关联。
您可以重新设计 TableB 来解决这个问题:
TableB (customer_no, ticket_type, quantity, order_dt, ...)
因此,对于客户 112,我们将在表 B 中拥有:
112, "GT_Child", 12 ...
112, "GT_Senior", 2 ...
因此,您可以通过加入 ticket_type(如果需要,也可以加入其他专栏)来回答您的问题。
如果可能,您应该将订单本身的详细信息移到第三个 table(我们称之为 TableC)并分配一个订单号。所以我们现在将拥有您拥有的 TableA,然后:
TableB (order_no, customer_no, ticket_type, quantity)
TableC (order_no, order_dt, season ...)
您可以使用 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
P.S。上面的查询在 SQL 服务器中有效。
编辑:
要在 MySQL
中模拟 PIVOT
,我们必须使用条件聚合:
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
加入问题
我有一个 table 有一个 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 有多个列,这些列有 names/headers 对应于描述列。
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 美元。按季节。
我唯一能确定的就是加入赛季,但我如何加入正确的列。 请指教。
我不认为你可以用你拥有的 table 做你想做的事。没有明确的方法将表 B 中的 "adult" 列与表 A 中包含 "GT Adult" 的行相关联。
您可以重新设计 TableB 来解决这个问题:
TableB (customer_no, ticket_type, quantity, order_dt, ...)
因此,对于客户 112,我们将在表 B 中拥有:
112, "GT_Child", 12 ...
112, "GT_Senior", 2 ...
因此,您可以通过加入 ticket_type(如果需要,也可以加入其他专栏)来回答您的问题。
如果可能,您应该将订单本身的详细信息移到第三个 table(我们称之为 TableC)并分配一个订单号。所以我们现在将拥有您拥有的 TableA,然后:
TableB (order_no, customer_no, ticket_type, quantity)
TableC (order_no, order_dt, season ...)
您可以使用 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
P.S。上面的查询在 SQL 服务器中有效。
编辑:
要在 MySQL
中模拟 PIVOT
,我们必须使用条件聚合:
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