如何在不重复自己的情况下对数据子集进行SQL查询?

时间:2012-01-31 16:47:10

标签: sql sqlite

我有一个包含应用统计信息的表格,我们说这些列是os_versionapp_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;

......遗憾的是,这不起作用。

1 个答案:

答案 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