2013-03-08 3 views
2

У меня есть запрос, который имеет подзапрос в качестве столбца поля, но я хочу использовать этот столбец поля в другом месте.Использование SubQuery в качестве столбца поля

SELECT c.country_code             AS 
     country_code, 
     c.dial_code              AS 
     dial_code, 
     (SELECT r.destination 
     FROM region r 
     WHERE r.country_code = c.country_code 
       AND r.dial_code = c.dial_code)       AS 
     destination, 
     c.start_time, 
     c.duration, 
     c.call_type, 
     c.customer_prefix             AS 
     customer_prefix, 
     c.vendor_prefix             AS 
     vendor_prefix, 
     (SELECT Round(r.rate, 3) 
     FROM rate r 
       INNER JOIN region re 
         ON r.region_id = re.id 
       INNER JOIN account_prefix ap 
         ON r.account_prefix_id = ap.id 
     WHERE re.country_code = c.country_code 
       AND re.dial_code = c.dial_code 
       AND ap.prefix = c.customer_prefix 
       AND ap.prefix_type = 0)         AS 
     **customer_rate**, 
     (SELECT Round(r.rate, 3) 
     FROM rate r 
       INNER JOIN region re 
         ON r.region_id = re.id 
       INNER JOIN account_prefix ap 
         ON r.account_prefix_id = ap.id 
     WHERE re.country_code = c.country_code 
       AND re.dial_code = c.dial_code 
       AND ap.prefix = c.vendor_prefix 
       AND ap.prefix_type = 1)         AS 
     **vendor_rate**, 
     (SELECT Round(r.rate, 3) 
     FROM rate r 
       INNER JOIN region re 
         ON r.region_id = re.id 
       INNER JOIN account_prefix ap 
         ON r.account_prefix_id = ap.id 
     WHERE re.country_code = c.country_code 
       AND re.dial_code = c.dial_code 
       AND ap.prefix = c.customer_prefix 
       AND ap.prefix_type = 0) - (SELECT Round(r.rate, 3) 
              FROM rate r 
               INNER JOIN region re 
                 ON r.region_id = re.id 
               INNER JOIN account_prefix ap 
                 ON r.account_prefix_id 
                  = ap.id 
              WHERE 
     re.country_code = c.country_code 
     AND re.dial_code = c.dial_code 
     AND ap.prefix = c.vendor_prefix 
     AND ap.prefix_type = 1) AS **unit_profit**, 
     unit_profit * duration 
FROM cdr c 
LIMIT 100; 

Как вы можете видеть, я хочу использовать unit_profit, customer_rate и vendor_rate. Как его достичь?

EDIT:

Любой учебник, который показывая присоединиться на просмотр?

+0

Вы не можете напрямую использовать псевдонимы, определенные в том же списке SELECT. Вам нужно будет использовать внешний запрос или (если ваша RDBMS поддерживает его) CTE. –

+0

Просьба подробно рассказать о внешнем запросе. Что такое CTE? Я использую базу данных mysql. – peterwkc

+0

Ответ Erwin Brandstetter дает пример внешнего запроса (дополнительный SELECT FROM из всех внутренних запросов. CTE означает * Общие выражения таблиц * (я думал о 'WITH'), но, судя по всему, MySQL не поддерживает его. –

ответ

2

Что вам нужно сделать, это взять все эти подзапросы сделали внутри flieds и создать объединение с таблицей CDR.

Это значительно улучшит производительность запроса и время отклика. Теперь вы выполняете 3 запроса для записей в CDR. В этой таблице (CDR) есть всего несколько записей в порядке, но если нет, это может поглотить массу процессора, памяти и дискового ввода-вывода.

The trick to do the "join" and show the info in the same format is to join 3 times the same subquery but with a different alias. 

select c.country_code, customer_rate_table.customer_rate 
from CDR c 
left outer join on (SELECT Round(r.rate, 3) customer_rate , re.country_code, 
         re.dial_code, re.dial_code, ap.prefix 
       FROM rate r 
       INNER JOIN region re 
         ON r.region_id = re.id 
       INNER JOIN account_prefix ap 
         ON r.account_prefix_id = ap.id 
       WHERE ap.prefix_type = 1 

) customer_rate_table 
ON customer_rate.country_code = c.country_code 
AND customer_rate.dial_code = c.dial_code 
AND customer_rate.prefix = c. customer_prefix 
left outer join on ({Same as above but with the right fields}) vendor_rate_table 
ON vendor_rate_table.country_code = c.country_code 
AND vendor_rate_table.dial_code = c.dial_code 
AND vendor_rate_table.prefix = c.vendor_prefix 

, а затем следующий стол ...

Этот код не является полным, но я думаю, что дает объяснение о том, что вам нужно сделать.

Спасибо!

@leo

+0

Что это за методы? Обычно мы присоединяемся к отношениям PK и FK, но в это время мы присоединяемся к таблице. Он не является исполняемым на mysql. – peterwkc

+0

Это, в основном, соединение, но вместо использования таблиц используется ad-hoc-просмотр с их собственными PK. – lemil77

+0

Взаимодействие с использованием представления, а не таблицы. Какое официальное название? – peterwkc

1

Коррелированные подзапросы, как у вас в вашем запросе, как правило, сосать, когда дело доходит до производительности. Поскольку вы только извлекаете 100 строк, это не должно быть слишком плохо, но если вы хотите быстрее, вам придется переписать свой запрос.

Проблема под рукой можно легко исправить с:

SELECT *, unit_profit * duration AS my_calc 
FROM (
    -- your query here 
    -- just without "unit_profit * duration" 
    -- and maybe without redundant column aliases 
    ) AS sub 
+0

Можете ли вы предоставить полный Пример – peterwkc

+0

@peterwkc: Этот * является * полным примером. Следуйте инструкциям и вставьте свой запрос в качестве подзапроса. –

+0

Я думаю, что ваш подход такой же, как и с lemil77, но разница - это представление о заявлении о соединении и представление из предложения. – peterwkc

Смежные вопросы