#sql #oracle #count #distinct-values
#sql #Oracle #подсчет #distinct-значения
Вопрос:
У меня есть эта таблица под названием «Anfrage». И это столбцы в «Таблице Anfrage»:
Я хочу подсчитать, сколько раз один и тот же клиент делал запросы. Поэтому я создал новый столбец «Menge_Anfrage», что означает количество запросов. Результат должен быть таким:
Я попытался использовать этот запрос:
`SELECT DISTINCT Count(*)
FROM Anfrage
WHERE KundenNr = 1
) AS "Menge Anfrage",`
но он возвращает «4» во всех строках в столбце «Menge Anfrage». Может кто-нибудь, пожалуйста, подсказать мне правильный запрос? Я использую инструменты SQL 1,8 b38. Большое вам спасибо.
Комментарии:
1. Немного запутался. у вас есть предложение
WHERE KundenNr = 1
, но в вашей таблице нет такой строки?2. Я просто случайно опробовал запрос. Если я не вставил предложение where, оно вернет «6» в качестве результата, а это не то, что я хотел. Вы видели результат моей таблицы? Это то, что я хочу.
3. Я понял, и я полагаю, что теперь у вас есть ответ 🙂
Ответ №1:
Похоже, вы хотите подсчитать, сколько раз происходит KundenNr. Для этого в вашу таблицу не нужно добавлять новый столбец; вы должны вычислять его каждый раз в запросе:
SELECT
KundenNr,
Project,
COUNT(*) OVER(PARTITION BY KundenNr) as Menge_Anfrage
FROM
Anfrage
Приведенный выше запрос является эквивалентом этого запроса, который работает в базах данных, которые не поддерживают аналитические функции:
SELECT
a.KundenNr,
a.Project,
x.Menge_Anfrage
FROM
Anfrage a
INNER JOIN (SELECT KundenNr, COUNT(*) as Menge_Anfrage FROM Anfrage GROUP BY KundenNr) x
ON a.KundenNr = x.KundenNr
OVER(PARTITION BY KundenNr)
выполняет практически то же, что и подзапрос GROUP BY в нижнем запросе; он разбивает набор данных на разделы (группы) на основе разных значений KundenNr, а COUNT(*) применяется к разделу, а не ко всему набору данных. Изучите и поймите, как работает нижний запрос, и тогда вы сможете понять верхний, если будете иметь в виду, что соединение между разделенным kundennr и строкой из таблицы выполняется автоматически.
Вот еще один способ написать то же самое:
SELECT
a.KundenNr,
a.Project,
(SELECT COUNT(*) FROM Anfrage x WHERE x.KundenNr = a.KundenNr) as Menge_Anfrage
FROM
Anfrage a
Вы могли бы подумать, что oracle будет для каждой строки в выходных данных запускать этот подзапрос, представленный в select . Логически это эквивалентно выполнению группирующего запроса с последующим объединением результатов или созданию хэш-таблицы разделов, которая сопоставляет KundenNr с Count, а затем сопоставляет их при подготовке результатов
Комментарии:
1. Да, вы поняли, что я имею в виду. Но, к сожалению, ваш запрос не сработал. Выдает ошибку ORA-01427: подзапрос возвращает более одной строки: (
2. Это будет не мой запрос, который выдает это, это будет то, что вы с ним сделали. Например, если вы использовали его в запросе insert like
INSERT INTO table (a,b) SELECT a,b,c FROM othertable
— этот запрос выбирает 3 значения, но insert указывает только 2; результат ошибки «слишком много значений». Как отмечалось в первой строке моего ответа, вы не должны хранить это количество в таблице, потому что тогда вам придется обновлять его каждый раз, когда вы добавляете строку. Просто вычислите его, когда это необходимо, выполнив этот запрос (с этим дополнительнымCOUNT(*) OVER(...)
в любое время, когда вы хотите получить обновленный счет3. @ella widya, не заменяйте запрос где-нибудь, как вы, возможно, уже сделали, кажется, что дается, но используйте это как окончательное решение.
4. @Caius Jard Я не использовал какую-либо вставку, и теперь она возвращает ошибку ORA-01427: Подзапрос возвращает более одной строки. Что делает это «OVER (РАЗДЕЛ ПО KundenNr)»?
5. Мой первый запрос не использует подзапрос. В моем втором запросе есть объединенный подзапрос, и для такого запроса совершенно законно возвращать более одной строки. Вы делаете что-то еще с запросом, заданным в ответе, и вы делаете это неправильно . «подзапрос возвращает более одной строки» встречается в запросах, подобных
SELECT * FROM table WHERE x = (SELECT y FROM othertable)
тому, где подзапросSELECT y FROM othertable
возвращает более одной строки. x не может быть одновременно равно более чем одному значению