#sql #sqlite #count #distinct
#sql #sqlite #граф #distinct
Вопрос:
Используя sqlite3, как я могу получить разные столбцы «count» для этого примера базы данных в памяти? Использование версии 3.27.2
Пример базы данных
CREATE TABLE events (
id1,
id2,
id3,
PRIMARY KEY (id1, id2)
);
INSERT INTO events (id1, id2, id3)
VALUES
(1,1,99),
(1,2,99),
(1,3,52),
(2,1,6),
(2,2,7),
(2,3,8)
;
.mode columns
.header on
SELECT * FROM events;
Желаемый печатный результат
Частичный успех Для первых двух новых столбцов работает следующее.
SELECT id1, count(id3) AS total_count, count(DISTINCT id3) AS unique_count
FROM events
GROUP BY id1;
Каков наилучший способ получить последний столбец? Следующие результаты error: no such column: total_count
SELECT id1, count(id3) AS total_count, count(DISTINCT id3) AS unique_count, (total_count - unique_count) AS repeated_count
FROM events
GROUP BY id1;
Комментарии:
1. Общее количество за вычетом уникального количества не дает вам число повторяющихся значений. Пожалуйста, посмотрите мой ответ на это. (Если вы просто хотели
total_count - unique_count
, вы могли бы просто использоватьcount(*) - count(distinct id3)
. Вы не можете получить доступ к псевдонимам в том же предложении, в котором вы их определяете.)
Ответ №1:
Если вам group by id1, id3
это нравится:
SELECT id1, id3, COUNT(*) counter
FROM events
GROUP BY id1, id3;
вы получаете количество строк для каждой комбинации id1, id3
:
id1 | id3 | счетчик |
---|---|---|
1 | 52 | 1 |
1 | 99 | 2 |
2 | 6 | 1 |
2 | 7 | 1 |
2 | 8 | 1 |
Теперь все, что вам нужно сделать, это:
- суммируйте столбец
counter
для каждогоid1
, чтобы получить столбецtotal_count
- подсчитайте количество строк для каждого
id1
, чтобы получить столбецunique_count
- подсчитайте количество строк для каждого
id1
столбца, в котором находится столбецcounter
> 1
, чтобы получить столбецrepeated_id3
Вы можете сделать это с SUM()
COUNT()
помощью оконных функций и:
SELECT DISTINCT id1,
SUM(COUNT(*)) OVER (PARTITION BY id1) AS total_count,
COUNT(*) OVER (PARTITION BY id1) AS unique_count,
SUM(COUNT(*) > 1) OVER (PARTITION BY id1) repeated_id3
FROM events
GROUP BY id1, id3;
Посмотрите демонстрацию.
Результаты:
id1 | total_count | unique_count | повторяемый идентификатор 3 |
---|---|---|---|
1 | 3 | 2 | 1 |
2 | 3 | 3 | 0 |
Ответ №2:
Возможно, попробуйте CTE. Я не проверял синтаксис, но это, по-видимому, допустимый вариант при просмотре документации SQLLite.
With X as
(
SELECT id1, count(id3) AS total_count, count(DISTINCT id3) AS unique_count
FROM events
GROUP BY id1;
)
select id1, total_count, unique_count, (total_count - unique_count) AS repeated_count
from X
Ответ №3:
Это не так просто 🙂
В
(1,1,99), (1,2,99), (1,3,52)
повторяется один идентификатор (99).
В
(1,1,99), (1,2,99), (1,3,52), (1,4,99)
снова повторяется один идентификатор (по-прежнему 99).
В
(1,1,99), (1,2,99), (1,3,52), (1,4,52)
повторяются два идентификатора (52 и 99).
При простом агрегировании по ID1 вы теряете эти знания. Вы видите, сколько было строк и сколько разных ID3, но не знаете, какие из этих ID3 имели дубликаты. Это означает, что вам нужен промежуточный шаг, предварительная агрегация перед окончательной агрегацией.
select
id1,
count(*) as total_count,
count(distinct id3) as unique_count,
count(case when cnt > 1 then 1 end) as repeated_count
from
(
select id1, id3, count(*) as cnt
from events
group by id1, id3
) pre_aggregated
group by id1
order by id1;