我有一个包含应用统计信息的表格,我们说这些列是os_version
和app_id
(简化)。我想列出某个应用程序的所有操作系统版本,对于每个操作系统版本,我想看到一些至少包含此操作系统版本的记录。示例数据:
app1 1.0
app1 2.0
app2 1.0
现在app1
我希望看到:
version | score | comments
--------+-------+---------
1.0 | 2 | there are two records having OS at least 1.0
2.0 | 1 | there is just one record with OS at least 2.0
现在,请原谅我无知的SQL,但我已经提出了这个问题:
SELECT
os_version,
-- number_of_records_having_at_least_this_version / number_of_all_records
(SELECT COUNT(*) FROM stats WHERE app_id='app1' AND os_version >= outer.os_version)/
(SELECT COUNT(*) FROM stats WHERE app_id='app1') AS score
FROM (SELECT * FROM stats WHERE app_id='app1') AS outer
GROUP BY os_version;
这很疯狂,因为我必须按应用ID过滤三次。是否可以先按应用ID进行过滤,然后使用生成的行集进行进一步操作?没有临时表?在SQLite?类似的东西:
SELECT
os_version,
(SELECT COUNT(*) FROM filtered WHERE os_version >= filtered.os_version)/
(SELECT COUNT(*) FROM filtered) AS score
FROM (SELECT * FROM stats WHERE app_id='app1') AS filtered
GROUP BY os_version;
......遗憾的是,这不起作用。
答案 0 :(得分:2)
我认为,如果我已经正确地理解了这个问题,那么这样的事情应该可以解决问题..
SELECT
s1.app_id,
s1.os_version,
count(*)
FROM stats s1 INNER JOIN stats s2 ON s1.app_id = s2.app_id
AND s2.os_version >= s1.os_version
GROUP BY s1.app_id, s1.os_version
编辑:这会返回app_id所展示的结果(与问题中的示例查询一样)
SELECT
s1.app_id,
s1.os_version,
count(*)
FROM stats s1 INNER JOIN stats s2 ON s1.app_id = s2.app_id
AND s2.os_version >= s1.os_version
WHERE s1.app_id = 'app1'
GROUP BY s1.app_id, s1.os_version
EDIT2:
SELECT
s1.app_id,
s1.os_version,
count(*)
FROM stats s1 INNER JOIN stats s2 ON s1.app_id = s2.app_id
AND s2.os_version >= s1.os_version
AND s1.app_id = 'app1'
GROUP BY s1.app_id, s1.os_version
EDIT3:绕过2.11< 2.7问题
SELECT
s1.app_id,
s1.os_version,
count(*)
FROM stats s1 INNER JOIN stats s2 ON s1.app_id = s2.app_id
AND CAST(REPLACE(s2.os_version, '.', '') TO INTEGER) >=
CAST(REPLACE(s1.os_version, '.', '') TO INTEGER)
AND s1.app_id = 'app1'
GROUP BY s1.app_id, s1.os_version