2013-03-08 176 views
2

我有查詢有子查詢作爲字段列,但我想在其他地方使用此字段列。使用子查詢作爲字段列

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。如何實現它?

編輯:

任何教程顯示加入視圖?

+0

您不能直接使用在同一個SELECT列表中定義的別名。您將需要使用外部查詢,或者(如果您的RDBMS支持它)CTE。 – 2013-03-08 02:02:37

+0

請詳細說明外部查詢。什麼是CTE?我正在使用mysql數據庫。 – peterwkc 2013-03-08 02:35:16

+0

Erwin Brandstetter的答案給出了一個外部查詢的例子(額外的SELECT FROM所有內部查詢,CTE代表* Common Tables Expressions *(我正在考慮'WITH'),但顯然MySQL不支持它 – 2013-03-08 02:41:13

回答

2

你需要做的是採取所有那些flieds內部完成子查詢,並建立與CDR表的連接。

這將大大提高查詢和響應時間的性能。你現在正在做的是在CDR上爲每條記錄執行3個查詢。如果這張表(CDR)只有幾條記錄是好的,但是如果不是這樣可能會消耗大量的處理器,內存和磁盤I/O。

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 2013-03-08 02:41:38

+0

這基本上是一個連接,但不是使用表使用與他們自己的PKs專用視圖 – lemil77 2013-03-08 02:48:08

+0

加入使用視圖而不是表。官方名稱是什麼? – peterwkc 2013-03-08 03:01:44

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 2013-03-08 02:34:30

+0

@peterwkc:這是一個完整的例子,按照說明插入你的查詢作爲子查詢 – 2013-03-08 03:23:41

+0

我認爲你的方法和lemil77是一樣的,但區別在於加入語句和從子句查看 – peterwkc 2013-03-08 03:48:29