Получить общее количество и первые 3 столбца - PullRequest
1 голос
/ 17 января 2020

У меня есть следующий SQL запрос:

SELECT TOP 3 accounts.username
    ,COUNT(accounts.username) AS count
FROM relationships
JOIN accounts ON relationships.account = accounts.id
WHERE relationships.following = 4
    AND relationships.account IN (
        SELECT relationships.following
        FROM relationships
        WHERE relationships.account = 8
        );

Я хочу вернуть общее количество счетов account.username и первых 3 account.username (в произвольном порядке). К сожалению, accounts.username и COUNT(accounts.username) не могут сосуществовать. Запрос работает нормально, удаляя один из них. Я не хочу отправлять запрос дважды с разными выбранными органами. Столбец count может охватывать 1000+, поэтому я бы предпочел рассчитать его в SQL, а не в коде.

Текущий запрос возвращает ошибку Column 'accounts.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause., которая никуда меня не привела, и это отличается от других вопросов, поскольку я не хочу использовать предложение 'group by'. Есть ли способ сделать это с FOR JSON AUTO?

Желаемый результат может быть:

+-------+----------+
| count | username |
+-------+----------+
| 1551  | simon1   |
| 1551  | simon2   |
| 1551  | simon3   |
+-------+----------+

или

+----------------------------------------------------------------+
| JSON_F52E2B61-18A1-11d1-B105-00805F49916B                      |
+----------------------------------------------------------------+
| [{"count": 1551, "usernames": ["simon1", "simon2", "simon3"]}] |
+----------------------------------------------------------------+

1 Ответ

1 голос
/ 17 января 2020

Если вы хотите отобразить общее количество строк, которые удовлетворяют условиям фильтра (и где username не равно нулю) в дополнительном столбце в вашем наборе результатов, то вы можете использовать оконные функции:

SELECT TOP 3
    a.username,
    COUNT(a.username) OVER() AS cnt
FROM relationships r
JOIN accounts a ON r.account = a.id
WHERE 
    r.following = 4
    AND EXISTS (
        SELECT 1 FROM relationships t1 WHERE r1.account = 8 AND r1.following = r.account
    )
;

Примечания:

  • , если username не имеет значения nullable, используйте COUNT(*) вместо COUNT(a.username): это более эффективно, так как не требуется, чтобы база данных проверяла каждое значение на нуль
  • псевдонимы таблиц облегчают написание, чтение и обслуживание запроса
  • Я обычно предпочитаю EXISTS вместо IN (но здесь это в основном дело вкуса, так как оба метода должны работать нормально для вашего случая использования)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...