Sql 分组+案例语句

Sql 分组+案例语句,sql,postgresql,group-by,case,aggregate-functions,Sql,Postgresql,Group By,Case,Aggregate Functions,我有一个工作查询,它根据硬件模型和结果对数据进行分组,但问题是有很多结果。我已经尝试将其降低到if result=0,然后保持为0,否则将其设置为1。这通常是有效的,但我最终会: day | name | type | case | count ------------+----------------+------+------+------- 2013-11-06 | modelA | 1 | 0 | 972 2013-

我有一个工作查询,它根据硬件模型和结果对数据进行分组,但问题是有很多结果。我已经尝试将其降低到if result=0,然后保持为0,否则将其设置为1。这通常是有效的,但我最终会:

    day     |      name      | type | case | count
------------+----------------+------+------+-------
 2013-11-06 | modelA         |    1 |    0 |   972
 2013-11-06 | modelA         |    1 |    1 |    42
 2013-11-06 | modelA         |    1 |    1 |     2
 2013-11-06 | modelA         |    1 |    1 |    11
 2013-11-06 | modelB         |    1 |    0 |   456
 2013-11-06 | modelB         |    1 |    1 |    16
 2013-11-06 | modelB         |    1 |    1 |     8
 2013-11-06 | modelB         |    3 |    0 | 21518
 2013-11-06 | modelB         |    3 |    1 |     5
 2013-11-06 | modelB         |    3 |    1 |     7
 2013-11-06 | modelB         |    3 |    1 |   563
而不是我试图实现的聚合,即每个类型/案例组合只有一行

    day     |      name      | type | case | count
------------+----------------+------+------+-------
 2013-11-06 | modelA         |    1 |    0 |   972
 2013-11-06 | modelA         |    1 |    1 |    55
 2013-11-06 | modelB         |    1 |    0 |   456
 2013-11-06 | modelB         |    1 |    1 |    24
 2013-11-06 | modelB         |    3 |    0 | 21518
 2013-11-06 | modelB         |    3 |    1 |   575
我的问题是:

select CURRENT_DATE-1 AS day, model.name, attempt.type, 
       CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END, 
       count(*) 
from attempt attempt, prod_hw_id prod_hw_id, model model
where time >= '2013-11-06 00:00:00'  
AND time < '2013-11-07 00:00:00'
AND attempt.hard_id = prod_hw_id.hard_id
AND prod_hw_id.model_id = model.model_id
group by model.name, attempt.type, attempt.result
order by model.name, attempt.type, attempt.result;
任何关于我如何做到这一点的建议都将非常棒


日期将始终在WHERE子句中定义,因此不会发生变化。名称、类型、resultcase和计数将有所不同。简而言之,对于任何给定的模型,我只希望每个类型+大小写组合只有一行。正如您在第一个结果集中所看到的,对于modelA,我有3行type=1和case=1,因为有许多结果值,我已将它们转换为0=0,其他任何值都为1。我希望将其表示为一行,并聚合计数,如示例数据集2所示。

尝试通过以下方式将其他两个非计数列添加到组中:

select CURRENT_DATE-1 AS day, 
model.name, 
attempt.type, 
CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END, 
count(*) 
from attempt attempt, prod_hw_id prod_hw_id, model model
where time >= '2013-11-06 00:00:00'  
AND time < '2013-11-07 00:00:00'
AND attempt.hard_id = prod_hw_id.hard_id
AND prod_hw_id.model_id = model.model_id
group by 1,2,3,4
order by model.name, attempt.type, attempt.result;

您的查询已经可以工作了-除了您遇到命名冲突或只是将输出列、大小写表达式与具有不同内容的源列结果混淆

...
GROUP BY model.name, attempt.type, attempt.result
...
或者提供与“发件人”列表中的任何列名不同的列别名,或者该列优先:

SELECT ...
     , CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
还请注意,我正在避免使用列名时间。这是一个标识符,不应该用作标识符。此外,你的时间显然是一段很长的时间,因此这很容易引起误解。

你能试试这个吗: 将案例陈述替换为以下陈述

Sum(CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END) as Count,

对于TSQL,我喜欢将case语句封装在外部apply中。这样可以避免编写两次case语句,允许在将来的联接中通过别名引用case语句,并且避免了位置引用的需要

select oa.day, 
model.name, 
attempt.type, 
oa.result
COUNT(*) MyCount 
FROM attempt attempt, prod_hw_id prod_hw_id, model model
WHERE time >= '2013-11-06 00:00:00'  
AND time < '2013-11-07 00:00:00'
AND attempt.hard_id = prod_hw_id.hard_id
AND prod_hw_id.model_id = model.model_id
OUTER APPLY (
    SELECT CURRENT_DATE-1 AS day,
     CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END result
    ) oa    
group by oa.day, 
model.name, 
attempt.type, 
oa.result
order by model.name, attempt.type, oa.result;

只有在上一步中引入别名时,才能使用别名。因此,SELECT子句中的别名可以在ORDER BY子句中使用,但不能在GROUP BY子句中使用

参考:Microsoft T-SQL文档供进一步阅读

FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP

希望这能有所帮助。

每种类型/案例对应哪一行。定义你的选择。日期和名称会不同吗?@ErwinBrandstetter,对于1个modelname,每个type/resultcase组合只有1行。有许多模型。每个模型都至少有一行,但由于成功/失败和类型不同,可能会有更多行。我将在数据集示例中添加更多内容。也许这会更有帮助。我试图按模式、类型、案例进行分组;对一般来说,它是有效的,但我只是想在其他唯一的行上聚合计数,其中只有计数是不同的。我想您的意思是通过将天添加到组中?我试过了,结果是一样的。你是说别的吗?我在select中有5个字段,其中3个已经存在,因此day是唯一的其他非计数字段。是。我把它们写在我的答案上:1,2,3,4。除了计数之外,您可能应该在讨论命名冲突时提到使用位置数字列引用的选项,而不仅仅是使用与散文建议不匹配的示例。我自己仍然觉得语法可读性差很多,但我知道有些人更喜欢它;引用手册,从而间接引用标准,了解何时以及如何使用输出列名,这是一项很好的工作。@IMSoP:Hmm。。但我在最后提到了位置参数。我已经在这个答案上下了很多功夫,所以我保持简短。读者可以翻阅手册以获得更多史诗般的阅读。链接在那里..长度上足够公平。在讨论了如何命名输出列以完全不使用输出列名,而是一个完全不同的问题解决方案之后,感觉很奇怪。也许就在例子说重写之前。。。使用另一种替代方法,即根据输出列的位置或其他内容引用输出列。而且,这些不是位置参数吗?只是位置参考…@IMSoP:你是对的,这个词是误导性的。TSQL如何适用于[postgresql]问题?这还不够。奇怪的是^^^当我在谷歌上搜索如何避免重复的案例陈述时,这个答案帮我找到了tSQL:D的“是”
select oa.day, 
model.name, 
attempt.type, 
oa.result
COUNT(*) MyCount 
FROM attempt attempt, prod_hw_id prod_hw_id, model model
WHERE time >= '2013-11-06 00:00:00'  
AND time < '2013-11-07 00:00:00'
AND attempt.hard_id = prod_hw_id.hard_id
AND prod_hw_id.model_id = model.model_id
OUTER APPLY (
    SELECT CURRENT_DATE-1 AS day,
     CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END result
    ) oa    
group by oa.day, 
model.name, 
attempt.type, 
oa.result
order by model.name, attempt.type, oa.result;
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP