我在main table
中有一些数据:
| id | Attendance | Accountability | Respect | |
|----|-------------------------|-------------------------|----------------------------|---|
| 1 | John was always on time | John is accountable | John is always respectful | |
| 2 | Ann never missed a day | Ann is very accountable | | |
| 3 | | | Dan was very disrespectful | |
我需要计算每行的非空单元格数,然后排序到范围。
示例:
首先计算非空单元格。
| id | Non-empty |
|----|-----------|
| 1 | 3 | # Row 1 has 3 comments
| 2 | 2 | # Row 2 has 2 comments and 1 empty cell
| 3 | 1 | # Row 3 has 1 comment and 2 empty cells
我们将此结果称为“表A”
然后根据留下的评论范围创建分组。 这是最终结果。
| id | Range | Count |
|----|--------------|-------|
| 1 | 1-2 comments | 2 | # 2 rows have between 1 and 2 comments
| 2 | 3-4 comments | 1 | # 1 row has between 3 and 4 comments
| 3 | 5+ comments | 0 | # 0 rows have more than 5 comments
我们将此结果称为“表B”
我做了什么
select
case
when Non-empty between 1 and 2 then '1-2 comments'
when Non-empty between 3 and 4 then '3-4 comments'
else then '5+ comments'
end as `Range`,
count(1) as `Count`
from `Table A`
group by `Range`
此查询应生成表A中的表B
我需要什么
从主表生成表B的单个SQL查询。
所以,我想我需要一个可以生成表A的查询,然后将它与上面的查询结合起来。
如果有更简单的方法从主表中获取表B,那么我欢迎它!
答案 0 :(得分:2)
{{1}}
答案 1 :(得分:0)
在这个例子中,我使用了:
Unpivot - 将表值表达式更改为另一个表
--- Source
CREATE TABLE Main
(
id INT ,
attendance VARCHAR(254) ,
Accountability VARCHAR(254) ,
Respect VARCHAR(254)
)
INSERT INTO Main
( id, attendance, accountability, respect )
VALUES ( 1, 'John was always on time', 'John is accountable',
'John is always respectful' ),
( 2, 'Ann never missed a day', 'Ann is very accountable', NULL ),
( 3, NULL, NULL, 'Dan was very disrespectful' )
--- Query
SELECT ROW_NUMBER() OVER(ORDER BY col) id,
col [range],
val [count]
FROM ( SELECT SUM(CASE WHEN ctr BETWEEN 1 AND 2 THEN 1
ELSE 0
END) [1-2 comments] ,
SUM(CASE WHEN ctr BETWEEN 3 AND 4 THEN 1
ELSE 0
END) [3-4 comments] ,
SUM(CASE WHEN ctr >= 5 THEN 1
ELSE 0
END) [5+ comments]
FROM ( SELECT attendance + Accountability + Respect [ctr]
FROM ( SELECT CASE WHEN attendance IS NOT NULL
OR attendance <> ''
THEN 1
ELSE 0
END attendance ,
CASE WHEN Accountability IS NOT NULL
OR Accountability <> ''
THEN 1
ELSE 0
END Accountability ,
CASE WHEN Respect IS NOT NULL
OR Respect <> '' THEN 1
ELSE 0
END Respect
FROM Main
) T
) Tmain
) TBL UNPIVOT( val FOR col IN ( [1-2 comments], [3-4 comments],
[5+ comments] ) ) UPVT
DROP TABLE Main
结果
id range count
-------------------- ------------------- -----------
1 1-2 comments 2
2 3-4 comments 1
3 5+ comments 0
(3 row(s) affected)
答案 2 :(得分:0)
这是对我有用的最终查询。
谢谢你@flip!你的回答让我最接近。
SELECT
case
when comments between 1 and 2 then '1-2 comments'
when comments between 3 and 4 then '3-4 comments'
else '5+ comments'
end as `Range`,
count(1) as `Count`
FROM(
SELECT id,
SUM(IF(Respect != '', 1, 0)) +
SUM(IF(Accountability != '', 1, 0)) +
SUM(IF(Attendance != '', 1, 0))
FROM `main table`
GROUP BY id
)AS T GROUP BY `Range`;