#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть три таблицы, из которых мне нужно получить информацию: Products, ProductOptions и OptionChoices. На данный момент это SQL, который я использую для получения указанной информации
select P.ProductId,P.Name,P.StoreId,PO.OptionId,OC.ChoiceName from Products P
inner join ProductOptions PO on P.ProductId=PO.ProductID
inner join OptionChoices OC on PO.OptionId=OC.OptionId
where P.ProductId=23317
который выводит это:
ProductId Name StoreID OptionId ChoiceName
23317 Admiral Ackbar Cereal 629 795 fish
23317 Admiral Ackbar Cereal 629 795 shrimp
23317 Admiral Ackbar Cereal 629 795 traps
23317 Admiral Ackbar Cereal 629 797 box
23317 Admiral Ackbar Cereal 629 797 casket
Что сделало бы мою жизнь намного проще, если бы я мог добавить еще один столбец, который дал бы мне общее количество вариантов для каждого идентификатора параметра. Таким образом, первая строка будет читать:
ProductId Name StoreID OptionId ChoiceName Count
23317 Admiral Ackbar Cereal 629 795 fish 3
Потому что есть 3 варианта с 795 в качестве идентификаторов опций. Я пробовал использовать различные комбинации group by и count, но безуспешно. У кого-нибудь есть идеи, чтобы указать мне правильное направление?
Редактировать: я использую SQL Server
Комментарии:
1. Какую версию SQL вы используете?
2. SQL server. Просто обновил мой вопрос
Ответ №1:
Вам нужен отдельный запрос для подсчета параметров. В этом примере MS SQL SERVER я использую коррелированный подзапрос для подсчета.
SELECT
P.ProductId,
P.Name,
P.StoreId,
PO.OptionId,
OC.ChoiceName,
(SELECT COUNT(*) FROM OptionChoices WHERE OptionId = OC.OptionId) AS option_count
FROM
Products P
INNER JOIN
ProductOptions PO
ON P.ProductId = PO.ProductID
INNER JOIN
OptionChoices OC
ON PO.OptionId = OC.OptionId
WHERE
P.ProductId=23317
Комментарии:
1. Это полностью сработало. Спасибо! Я собираюсь потратить некоторое время на чтение этого запроса, чтобы понять это.
2. Проблемы с производительностью будут полностью зависеть от индексации и размера рассматриваемого набора данных. Как и в этом запросе
P.ProductId=23317
, коррелированный подзапрос действительно будет иметь отношение только к небольшому количеству записей. Также обратите внимание, что SQL Server довольно хорошо оптимизирует это. Тем не менее, объединение(SELECT OptionID, COUNT(*) FROM OptionChoices GROUP BY OptionID)
будет быстрее для больших наборов данных.3. Это не для чего-либо, связанного с производством. Мне нужно сгенерировать несколько отчетов, и это просто помогает мне быстрее выполнить задачу.
Ответ №2:
Вы так близко…
Выполните:
Select p.Productid, p.name,
P.storeid,P.optionid, Count(choicename)
From ( your actual query here) p
Group by p.productid,p.name,p.storeid,p.optionid
Комментарии:
1. Это удаляет option_name из результирующего набора. Оператору требуется каждая запись вместе с количеством записей в группе…
2. Столбец ‘OptionChoices.Name ‘ недопустимо в списке выбора, поскольку оно не содержится ни в агрегатной функции, ни в предложении GROUP BY.
3. Уважаемые коллеги, я написал свое заявление из ячейки, и в мобильной версии довольно сложно увидеть все это целиком, если требуется значение option_name, то его следует выбрать; если повторяющиеся значения нежелательны, то они должны быть сгруппированы по этому столбцу. Идея состоит в том, чтобы выбрать все повторяющиеся столбцы и подсчитать те, которые не повторяются, группируя по всем тем, которые не включены в счетчик.
4. Оператору требуется каждый элемент в наборе, без группировки, удаления дублирования или любой другой функциональности. Затем в качестве дополнительного поля требуется количество подгрупп. Этого нельзя достичь только одной ссылкой на таблицу OptionChoices.
5. @dems тогда я допустил ошибку, я думал, что ему нужны только отдельные столбцы количество вариантов для одного и того же продукта.
Ответ №3:
Попробуйте это 🙂
select P.ProductId,P.Name,P.StoreId, PO.OptionId, max(OC.ChoiceName), count(P.ProductId) from Products P
inner join ProductOptions PO on P.ProductId=PO.ProductID
inner join OptionChoices OC on PO.OptionId=OC.OptionId
where P.ProductId=23317
GROUP BY P.ProductId, PO.OptionId
проблема в том, что вы не знаете, что вы получаете для поля «OC.ChoiceName» — вы также можете использовать GROUP_CONCAT (OC.ChoiceName)
смотрите: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
Результат для max:
ProductId Name StoreID OptionId ChoiceName Count
23317 Admiral Ackbar Cereal 629 795 traps 3
23317 Admiral Ackbar Cereal 629 797 box 2
Результат для GROUP_CONCAT (только MySQL !!):
ProductId Name StoreID OptionId ChoiceName Count
23317 Admiral Ackbar Cereal 629 795 fish,shrimp,traps 3
23317 Admiral Ackbar Cereal 629 797 box,casket 2
Комментарии:
1. Облом, получаю ошибки для каждого. Для первого: столбец «Продукты. ProductID’ недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY . Для второго: неправильный синтаксис рядом с ‘GROUP_CONCAT’. Использование Sql server, если это помогает
2. GROUP_CONCAT — это MySQL — Извините — забыл «P.» и «PO». в «GROUP BY» — попробуйте еще раз
Ответ №4:
select
P.ProductId
, P.Name
, P.StoreId
, PO.OptionId
, OC.ChoiceName
, count(PO.OptionId) over (partition by P.StoreId) as OpCount
from Products P
inner join ProductOptions PO on P.ProductId = PO.ProductID
inner join OptionChoices OC on PO.OptionId = OC.OptionId
where P.ProductId = 23317