Выберите количество строк в другой таблице в операторе Postgres SELECT - PullRequest
50 голосов
/ 27 декабря 2010

Я не знаю, как это сформулировать, поэтому, пожалуйста, помогите мне с названием. :)

У меня есть две таблицы. Давайте назовем их A и B. Таблица B имеет внешний ключ a_id, который указывает на A.id. Теперь я хотел бы написать оператор SELECT, который выбирает все записи A, с дополнительным столбцом, содержащим количество B записей на A строку для каждой строки в наборе результатов.

Я сейчас использую Postgresql 9, но думаю, что это будет общий вопрос SQL?

EDIT:

В конце концов я выбрал решение для триггерного кэша, где A.b_count обновляется с помощью функции каждый раз, когда B изменяется.

Ответы [ 5 ]

79 голосов
/ 27 декабря 2010
SELECT A.*, (SELECT COUNT(*) FROM B WHERE B.a_id = A.id) AS TOT FROM A
26 голосов
/ 04 ноября 2014

Я думаю, что комментарий @intgr в другом ответе настолько ценен, что я выдвигаю его как альтернативный ответ, поскольку этот метод позволяет эффективно фильтровать вычисленный столбец.

SELECT
  a.*,
  COUNT(b.id) AS b_count

FROM a
INNER JOIN b on b.a_id = a.id
WHERE a.id > 50 AND b.ID < 100 -- example of filtering joined tables, optional

GROUP BY a.id
HAVING COUNT(b.id) > 10 -- example of filtering calculated column, optional
ORDER BY a.id
11 голосов
/ 27 декабря 2010

Решение подзапроса, приведенное выше, неэффективно. Триггерное решение, вероятно, лучше всего подходит для базы данных, в основном читаемой, но для записи вот подход соединения, который будет работать лучше, чем подзапрос:

SELECT a.id, a.xxx, count(*)
FROM a JOIN b ON (b.a_id = a.id)
GROUP BY a.id, a.xxx

Если вы используете Django ORM, вы можете просто написать:

res = A.objects.annotate(Count('b'))
print res[0].b__count  # holds the result count
5 голосов
/ 07 декабря 2016

Принятый ответ неэффективен (медленен) на основании моих тестов. Подзапрос таблицы B выполняется для каждой строки таблицы A. Я использую следующий подход, основанный на группировании и объединении. Работает намного быстрее:

SELECT A.id, QTY.quantity FROM A
LEFT JOIN
    (SELECT COUNT(B.a_id) AS quantity, B.a_id FROM B GROUP BY B.a_id) AS QTY
ON A.id = QTY.a_id

Другой вариант:

SELECT A.id, COUNT(B.a_id) AS quantity FROM A
LEFT JOIN B ON B.a_id = A.id
GROUP BY A.id
0 голосов
/ 27 декабря 2010

Чтобы ответить на мой вопрос:

SELECT a.id, a.other_column, ..., 
(SELECT COUNT(*) FROM b where b.a_id = a.id) AS b_count
FROM a;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...