按两个计数的划分结果排序

时间:2014-01-09 12:47:59

标签: sql

我有一个像这样的查询:

SELECT
  type,
  count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
  count(case when STATUS = 'Failed' then 1 end) as FAILED,
  count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
  count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
  count(case when STATUS = 'Blocked' then 1 end) as Blocked,
  count(case when STATUS = 'Passed' then 1 end) as PASSED,
  count(case when STATUS <> 'N/A' then 1 end) as TOTAL

FROM
  table

GROUP BY
  type

我想订购结果,以便具有最高传递百分比类型的行位于顶部。

我虽然喜欢:

ORDER BY
  "PASSED"/"TOTAL" DESC

但它不起作用。

你有什么想法实现这个目标吗?

谢谢,

5 个答案:

答案 0 :(得分:2)

如果在SELECT中引用ORDER BY中定义的列别名,则必须单独使用它们。不在表达中。

您可以使用派生表。

SELECT *
FROM 
(
/* Your Query here*/
) T
ORDER BY PASSED/TOTAL DESC

您可能还需要将PASSED强制转换为数字,以避免整数除法,具体取决于您的DBMS。

答案 1 :(得分:2)

您可以在ORDER BY

中使用表达式
SELECT
  type,
  count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
  count(case when STATUS = 'Failed' then 1 end) as FAILED,
  count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
  count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
  count(case when STATUS = 'Blocked' then 1 end) as Blocked,
  count(case when STATUS = 'Passed' then 1 end) as PASSED,
  count(case when STATUS <> 'N/A' then 1 end) as TOTAL

FROM
  table

GROUP BY
  type
ORDER BY 
  count(case when STATUS = 'Passed' then 1 end)/count(case when STATUS <> 'N/A' then 1 end) desc

但这可能会产生division by zero例外,你必须检查是否计数(STATUS&lt;&gt;'N / A'然后1结束时的情况)不为零。

另一种解决方案是使用子查询 - 您将初始查询包含在子查询中,然后您可以在SQL中将此子查询作为简单表进行排序,限制或过滤

SELECT * 
FROM (
    SELECT
      type,
      count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
      count(case when STATUS = 'Failed' then 1 end) as FAILED,
      count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
      count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
      count(case when STATUS = 'Blocked' then 1 end) as Blocked,
      count(case when STATUS = 'Passed' then 1 end) as PASSED,
      count(case when STATUS <> 'N/A' then 1 end) as TOTAL

    FROM
      table

    GROUP BY
      type
) AS SUB_DATA
ORDER BY PASSED/TOTAL DESC

如果您使用PostgreSQL,可以使用WITH构造(我非常喜欢)。

WITH _records as (
    SELECT
      type,
      count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
      count(case when STATUS = 'Failed' then 1 end) as FAILED,
      count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
      count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
      count(case when STATUS = 'Blocked' then 1 end) as Blocked,
      count(case when STATUS = 'Passed' then 1 end) as PASSED,
      count(case when STATUS <> 'N/A' then 1 end) as TOTAL

    FROM
      table

    GROUP BY
      type
)
SELECT * 
FROM _records
ORDER BY PASSED/TOTAL DESC

答案 2 :(得分:1)

SELECT *, (PASSED / TOTAL) [percent] FROM
(   SELECT
      type,
      count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
      count(case when STATUS = 'Failed' then 1 end) as FAILED,
      count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
      count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
      count(case when STATUS = 'Blocked' then 1 end) as Blocked,
      count(case when STATUS = 'Passed' then 1 end) as PASSED,
      count(case when STATUS <> 'N/A' then 1 end) as TOTAL

    FROM
      table

    GROUP BY
      type ) T
ORDER BY [percent]

答案 3 :(得分:1)

您的代码在sql server中工作,但我认为不在oracle中。尝试:

SELECT
  type,
  count(case when STATUS = 'N/A' then 1 end) as NOTAPPLICABLE,
  count(case when STATUS = 'Failed' then 1 end) as FAILED,
  count(case when STATUS = 'No Run' then 1 end) as NO_RUN,
  count(case when STATUS = 'Not Completed' then 1 end) as NOT_COMPLETE,
  count(case when STATUS = 'Blocked' then 1 end) as Blocked,
  count(case when STATUS = 'Passed' then 1 end) as PASSED,
  count(case when STATUS <> 'N/A' then 1 end) as TOTAL,
  count(case when STATUS = 'Passed' then 1 end) / count(case when STATUS <> 'N/A' then 1 end) as sort
FROM
  table

GROUP BY
  type
ORDER BY 9
  sort DESC

答案 4 :(得分:1)

您的方法存在两个问题:

  1. 正如其他人已经指出的那样,你不能使用列别名 计算。写ORDER BY PASSED/TOTAL DESC
  2. 而不是ORDER BY count(case when STATUS = 'Passed' then 1 end) / count(case when STATUS <> 'N/A' then 1 end)
  3. 如果你将PASSED除以TOTAL,并且PASSED小于TOTAL,你就会 因此总是得到0。就像select 5/10将返回0一样 而不是0.5 - 因为两个值都是整数,所以你会得到整数。 select 1.0*5/10将返回0.5