2015-01-08 3 views
0

Имея соединяющий вопросSQL не может понять, как соединить правильно

У меня есть одна таблицы, которая имеет идентификатор и описание столбец сезоны являются новыми, но описания повторяются. так что мы можем иметь цену для взрослых на сезон 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 имеет несколько столбцов эти столбцы имеют имена/заголовки, соответствующие колонки описания.

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 необходимо заплатить 10 долларов США за каждый из 23 билетов. по сезону.

Единственное, что я могу сделать наверняка, - это присоединиться к сезону, но как я могу присоединиться к правильной колонке. Просьба сообщить.

+1

Если возможно, я бы изменил 'tableA', чтобы иметь столбцы' adult_price', 'child_price' и' senior_price', таким образом, структура представляет собой одну строку для каждого сезона, и это сделает то, что вы пытаетесь сделать намного проще. – dursk

+0

Это может на самом деле иметь большой смысл, так что у нас может быть одна строка за сезон. Я попробую это. Спасибо. – YelizavetaYR

+0

FWIW, это НЕ то, что я бы сделал !!! – Strawberry

ответ

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 

Учитывая выборочные данные, приведенные в ОП, выше производит STH как:

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.

EDIT:

Для имитации 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

1

Я не думаю, что вы можете делать то, что хотите, с таблицами, которые у вас есть. Не существует четкого способа связать столбец «взрослый» в TableB с строкой, содержащей «GT Adult» в TableA.

Вы можете перепроектировать TableB, чтобы решить эту проблему:

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

Так что для клиента 112 мы имеем в TableB:

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 ...) 
+0

На самом деле, customer_no было бы лучше в TableC. В противном случае это не нормализуется (я понимаю, что клиент может заказать более одного типа билетов). – TonyJenkins