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