【问题标题】:Using SubQuery as Field Column使用子查询作为字段列
【发布时间】:2013-03-08 01:57:36
【问题描述】:

我的查询具有子查询作为字段列,但我想在其他地方使用此字段列。

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。如何实现呢?

编辑:

任何显示加入视图的教程?

【问题讨论】:

  • 您不能直接使用在同一个 SELECT 列表中定义的别名。您将需要使用外部查询,或者(如果您的 RDBMS 支持)CTE。
  • 请详细说明外部查询。什么是 CTE?我正在使用 mysql 数据库。
  • Erwin Brandstetter 的回答给出了一个外部查询的例子(额外的 SELECT FROM all inside 查询。CTE 代表 Common Tables Expressions(我在考虑 WITH)但显然是 MySQL不支持它。

标签: mysql sql subquery


【解决方案1】:

您需要做的是获取所有在飞行中完成的子查询,并创建与 CDR 表的连接。

这将大大提高查询的性能和响应时间。您现在正在做的是为每个 CDR 的记录执行 3 个查询。如果这个表(CDR)只有几条记录是可以的,但如果没有这可能会消耗大量的处理器、内存和磁盘 I/O。

执行“加入”并以相同格式显示信息的技巧是加入 3 次相同的子查询,但使用不同的别名。

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

【讨论】:

  • 这种技术叫什么?通常,我们使用 PK 和 FK 关系加入,但这次我们使用表加入。不能在 mysql 上执行。
  • 这基本上是一个连接,但不是使用表,而是使用具有自己 PK 的临时视图
  • 使用视图而不是表格加入。正式名称是什么?
【解决方案2】:

相关子查询 就像您在查询中使用的那样,在性能方面通常很糟糕。由于您只检索 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

【讨论】:

  • 你能提供一个完整的例子吗?
  • @peterwkc:这一个完整的例子。按照说明插入您的查询作为子查询。
  • 我认为您的方法与 lemil77 相同,但不同之处在于对 join 语句的看法和对 from 子句的看法。
  • 这种技术叫什么?
  • @peterwkc:子查询或子选择。很基础的东西。 view 是不同的东西。与大多数其他广泛使用的 RDBMS 不同,MySQL 不支持 CTE (Common Table Expression)。最后一个链接是 Postgres 手册,因为 MySQL 没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多