我有一个包含重复字段的表,需要CROSS JOIN UNNEST
,我希望能够获得原始嵌套行的计数。例如。
SELECT studentId, COUNT(1) as studentCount
FROM myTable
CROSS JOIN UNNEST classes
WHERE classes.id in ('1', '2')
现在,如果学生在1级和2级,它将在studentCount
中计算该学生两次。
我知道我可以count(distinct(student.id))
来解决这个问题,但这最终会比简单计数慢得多。它没有利用每个学生只有一行的事实。
那么有什么方法可以在取消之前计算原始行的计数(但是在where子句之后)但是仍然在查询中包含了这个行?
请注意,这必须是标准SQL。
答案 0 :(得分:2)
我理解你的挑战"仅显示来自1级和2级课程的学生,同时仍显示所有班级的学生总数。如果是这样 - 见下文
#standardSQL
SELECT studentId, studentCount
FROM myTable
CROSS JOIN (SELECT COUNT(1) studentCount FROM myTable)
WHERE studentId IN (
SELECT studentID FROM UNNEST(classes) AS classes
WHERE classes.id IN ('1', '2')
)
您可以使用虚拟数据进行测试/播放,如下所示
#standardSQL
WITH myTable AS (
SELECT 1 AS studentId, [STRUCT<id STRING>('1'),STRUCT('2'),STRUCT('3')] AS classes UNION ALL
SELECT 2, [STRUCT<id STRING>('4'),STRUCT('5')]
)
SELECT studentId, studentCount
FROM myTable
CROSS JOIN (SELECT COUNT(1) studentCount FROM myTable)
WHERE studentId IN (
SELECT studentID FROM UNNEST(classes) AS classes
WHERE classes.id IN ('1', '2')
)
如果您想要的输出与我猜测的不同,您仍然会发现以上对计算studentCount
非常有用
答案 1 :(得分:1)
刚刚给出原始约束 - 需要取消需要并且您需要计算学生数量 - 您可以使用此表单的查询:
SELECT studentId, (SELECT COUNT(*) FROM myTable) AS studentCount
FROM myTable
CROSS JOIN UNNEST classes
WHERE classes.id in ('1', '2')