【问题标题】:using inline select on temporary table在临时表上使用内联选择
【发布时间】:2012-09-10 11:42:35
【问题描述】:

我在报告工具中使用 mysql。 我有一个临时表,我正在填写一些查询,然后显示临时表中的数据。

我的表结构是

Prim_key    starttime             endtime          timediff
1       2012-07-20 00:00:0    2012-07-22 10:55:32   39332
2       2012-07-20 04:50:13   2012-07-22 10:55:32   158719
3       2012-07-20 10:00:00   2012-07-22 00:00:05   5

我需要显示一个时间百分比 45 之间。 我已经编写了以下查询,但出现 Status 1137 - Can't reboot table: 't_results'

的错误
Expected result:

|   % of less than 30 min   | % of between 30 - 45 |    % of greater than 45 mins |

查询是

SELECT prim_key key, (
  SELECT count(*)*100 / (
      SELECT count(*)
      FROM t_results 
      WHERE timediff > 0 )
  FROM   t_results 
  WHERE  (timediff /60)  < 30
  ) less30, (
  SELECT count(*)*100 / (
     SELECT count(*)
     FROM t_results 
     WHERE timediff > 0 )
  FROM   t_results 
  WHERE  (timediff /60)  >=  30  and (timediff /60)  <=  45 
  ) bet3045, 
  (SELECT count(*)*100 / (
      SELECT count(*)
      FROM t_results 
     WHERE timediff > 0 ) 
  FROM t_results 
  WHERE  (timediff /60)  > 45 
 )  great45 
FROM t_results 
WHERE 1 = 1 AND 1 =1 
GROUP BY prim_key

还有别的写法吗?

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    临时表不能在同一个查询中被引用两次。

    http://bugs.mysql.com/bug.php?id=10327

    编辑

    实际上,稍微思考一下(因为您需要一个支点)我相信您的查询将采用以下形式

    (第二次编辑,格式为百分比)

    SET @numRows := (SELECT COUNT(*) FROM t_results WHERE timediff > 0 );
    SELECT COUNT(CASE WHEN (timediff /60)  < 30 THEN timediff ELSE NUll END) * 100 /@numRows  less30, 
        COUNT(CASE WHEN (timediff /60)  >=  30  and (timediff /60)  <=  45  THEN timediff ELSE NUll END) * 100 /@numRows bet3045, 
        COUNT(CASE WHEN (timediff /60)  > 45  THEN timediff ELSE NUll END) * 100 /@numRows great45 
    FROM t_results WHERE timediff > 0 
    

    应该做的伎俩。除非我犯了一个相当愚蠢的错误。我通常这样做:)

    【讨论】:

    • 关于如何构建查询的进一步说明,我将在您的选择中实现一个 case 语句,然后按此分组。
    • 这个查询没有给出所需的结果。最值得注意的是它不返回百分比。此外,它添加了原始查询中不存在的 WHERE 子句。
    • 这里的 where 子句实际上是问题中陈述的每个子查询中存在的那个的全局版本。鉴于查询的结构,有人可能会争辩说,将计数转换为百分比是相当微不足道的(因为枢轴是迄今为止更难绕开的部分),但公平点。我会更新的。
    • 子查询中的 WHERE 子句不会影响主查询产生的行数。主查询中的 WHERE 子句可以。
    • 啊,是的,我明白你的意思。然而,在我看来,总行数被认为是那些具有正时间差异的行,因此(至少在我看来)在主查询中是有意义的。甚至可以争辩说整个 time_diff > 0 是相当多余的,因为很难想到结束时间早于开始时间的情况。我敢肯定 user1606540​​ 迟早会清除它的:)
    【解决方案2】:

    @user1051643 是对的,您不能在查询中多次使用临时表。可惜,迟钝等等,但就是这样。

    也就是说,您想通过查询实现什么目标?令我感到非常奇怪的是,您的主要查询执行 GROUP BY prim_key。假设 prim_key 是主键,并且您的查询没有连接,这似乎是多余的,因为 GROUP BY 查询结果的概念主键始终由 GROUP BY 列表中的列精确定义。 IE。你的 GROUP BY 是多余的。

    然后在您的 SELECT 列表中,您对 t_results 执行了一堆聚合查询,但它们似乎都与主查询的当前行无关。这意味着您可以轻松地将其重写为一系列单独的查询而不会损失任何性能。但最重要的是,它让我觉得你没有足够精确地定义你想要解决的问题。

    更新:

    select 100 * sum(
                     if (timediff < 30*60, 1, 0)
                 ) / count(timediff)  
           AS "% of less than 30 min"
    ,      100 * sum(
                     if (timediff between 30*60 and 45*60, 1, 0)
                 ) / count(timediff)  
           AS "% of between 30 - 45"
    ,      100 * sum(
                     if (timediff > 45*60, 1, 0)
                 ) / count(timediff) 
           AS "% of greater than 45 mins"
    from   t_results
    

    【讨论】:

      猜你喜欢
      • 2018-12-08
      • 1970-01-01
      • 2021-12-13
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      • 2013-07-15
      相关资源
      最近更新 更多