Как заставить SQL-запрос работать с подмножеством данных, не повторяя себя? - PullRequest
0 голосов
/ 31 января 2012

У меня есть таблица со статистикой приложения, скажем, столбцы 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;

Это безумие, так как мне приходится фильтровать по идентификатору приложения три раза. Можно ли сначала фильтровать по идентификатору приложения, а затем использовать полученный набор строк для дальнейших операций? Без временной таблицы? В 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 Ответ

2 голосов
/ 31 января 2012

Я думаю, если я правильно понял вопрос, то что-то вроде этого должно сработать ..

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

РЕДАКТИРОВАТЬ 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
                                  AND s1.app_id = 'app1'
GROUP BY s1.app_id, s1.os_version

РЕДАКТИРОВАТЬ3: Чтобы обойти проблему 2,11 <2,7 </p>

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...