Выберите несколько столбцов из таблицы, но сгруппируйте по одному

Имя таблицы - "OrderDetails", столбцы приведены ниже:

OrderDetailID || ProductID || ProductName || OrderQuantity

Я пытаюсь выбрать несколько столбцов и сгруппировать по ProductID с суммой OrderQuantity.

 Select ProductID,ProductName,OrderQuantity Sum(OrderQuantity)
 from OrderDetails Group By ProductID

Но, конечно, этот код выдает ошибку. Я должен добавить другие имена столбцов для группировки, но это не то, что я хочу, и поскольку в моих данных много элементов, поэтому результаты неожиданны.

Пример запроса данных:

ProductID, ProductName, OrderQuity от OrderDetails

Результаты ниже:

 ProductID     ProductName    OrderQuantity
    1001          abc               5
    1002          abc               23    (ProductNames can be same)
    2002          xyz               8
    3004          ytp               15
    4001          aze               19
    1001          abc               7     (2nd row of same ProductID)

Ожидаемый результат:

 ProductID     ProductName    OrderQuantity
    1001          abc               12    (group by productID while summing)
    1002          abc               23
    2002          xyz               8
    3004          ytp               15
    4001          aze               19

Как выбрать несколько столбцов и столбец Group By ProductID, поскольку ProductName не является уникальным?

При этом также получите сумму столбца OrderQuantity.

Ответы

Ответ 1

Я использую этот трюк для группировки по одному столбцу, когда у меня есть выбор нескольких столбцов:

SELECT MAX(id) AS id,
    Nume,
    MAX(intrare) AS intrare,
    MAX(iesire) AS iesire,
    MAX(intrare-iesire) AS stoc,
    MAX(data) AS data
FROM Produse
GROUP BY Nume
ORDER BY Nume

Это работает.

Ответ 2

Ваши данные

DECLARE @OrderDetails TABLE 
(ProductID INT,ProductName VARCHAR(10), OrderQuantity INT)

INSERT INTO @OrderDetails VALUES
(1001,'abc',5),(1002,'abc',23),(2002,'xyz',8),
(3004,'ytp',15),(4001,'aze',19),(1001,'abc',7)

запрос

 Select ProductID, ProductName, Sum(OrderQuantity) AS Total
 from @OrderDetails 
 Group By ProductID, ProductName  ORDER BY ProductID

Результат

╔═══════════╦═════════════╦═══════╗
║ ProductID ║ ProductName ║ Total ║
╠═══════════╬═════════════╬═══════╣
║      1001 ║ abc         ║    12 ║
║      1002 ║ abc         ║    23 ║
║      2002 ║ xyz         ║     8 ║
║      3004 ║ ytp         ║    15 ║
║      4001 ║ aze         ║    19 ║
╚═══════════╩═════════════╩═══════╝

Ответ 3

Вы можете попробовать это:

Select ProductID,ProductName,Sum(OrderQuantity) 
 from OrderDetails Group By ProductID, ProductName

Group By вас требуется только Group By столбцы, в которых нет функции агрегирования в предложении Select. Так что в этом случае вы можете просто использовать Group By ProductID и ProductName.

Ответ 4

== == EDIT

Я снова проверил ваш вопрос и пришел к выводу, что этого не может быть сделано.

ProductName не является уникальным, оно должно быть частью Group By или исключено из ваших результатов.

Например, как SQL представит эти результаты вам, если вы Group By только ProductID?

ProductID | ProductName | OrderQuantity 
---------------------------------------
1234      | abc         | 1
1234      | def         | 1
1234      | ghi         | 1
1234      | jkl         | 1

Ответ 5

    WITH CTE_SUM AS (
      SELECT ProductID, Sum(OrderQuantity) AS TotalOrderQuantity 
      FROM OrderDetails GROUP BY ProductID
    )
    SELECT DISTINCT OrderDetails.ProductID, OrderDetails.ProductName, OrderDetails.OrderQuantity,CTE_SUM.TotalOrderQuantity 
    FROM 
    OrderDetails INNER JOIN CTE_SUM 
    ON OrderDetails.ProductID = CTE_SUM.ProductID

Пожалуйста, проверьте, работает ли это.

Ответ 6

Функция mysql GROUP_CONCAT может помочь https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat

SELECT ProductID, GROUP_CONCAT(DISTINCT ProductName) as Names, SUM(OrderQuantity)
FROM OrderDetails GROUP BY ProductID

Это вернуло бы:

ProductID     Names          OrderQuantity
1001          red            5
1002          red,black      6
1003          orange         8
1004          black,orange   15

Идея, аналогичная той, которую написал @Urs Marian здесь fooobar.com/questions/330619/...

Ответ 7

Вы можете попробовать следующий запрос. Я предполагаю, что у вас есть одна таблица для всех ваших данных.

SELECT OD.ProductID, OD.ProductName, CalQ.OrderQuantity
FROM (SELECT DISTINCT ProductID, ProductName
      FROM OrderDetails) OD
INNER JOIN (SELECT ProductID, OrderQuantity SUM(OrderQuantity)
            FROM OrderDetails
            GROUP BY ProductID) CalQ
ON CalQ.ProductID = OD.ProductID

Ответ 8

Я просто хотел добавить более эффективный и общий способ решения такого рода проблем. Основная идея заключается в работе с подзапросами.

сделайте свою группу по и присоединитесь к той же таблице по идентификатору таблицы.

Ваш случай более конкретен, поскольку ваш productId не уникален, поэтому есть 2 способа решить эту проблему.

Я начну с более конкретного решения: поскольку ваш productId не является уникальным, нам потребуется дополнительный шаг, который заключается в выборе DISCTINCT продукта DISCTINCT после группировки и выполнения подзапроса, как DISCTINCT ниже:

WITH CTE_TEST AS (SELECT productId, SUM(OrderQuantity) Total
                    FROM OrderDetails
                    GROUP BY productId)
SELECT DISTINCT(OrderDetails.ProductID), OrderDetails.ProductName, CTE_TEST.Total
FROM OrderDetails 
INNER JOIN CTE_TEST ON CTE_TEST.ProductID = OrderDetails.ProductID

это возвращает именно то, что ожидается

 ProductID     ProductName         Total
    1001          abc               12    
    1002          abc               23
    2002          xyz               8
    3004          ytp               15
    4001          aze               19

Но есть более чистый способ сделать это. Я предполагаю, что ProductId является внешним ключом таблицы продуктов, и я предполагаю, что в этой таблице должен быть и первичный ключ OrderId (уникальный).

в этом случае есть несколько шагов, чтобы включить дополнительные столбцы при группировании только по одному. Это будет то же решение, что и следующее

Давайте возьмем эту таблицу t_Value например:

enter image description here

Если я хочу сгруппировать по описанию, а также отобразить все столбцы.

Все, что мне нужно сделать, это:

  1. создать подзапрос WITH CTE_Name с вашим столбцом GroupBy и условием COUNT
  2. выберите все (или все, что вы хотите отобразить) из таблицы значений и итоговое значение из CTE
  3. INNER JOIN с CTE в столбце ID (первичный ключ или уникальное ограничение)

и это оно!

Вот запрос

WITH CTE_TEST AS (SELECT Description, MAX(Id) specID, COUNT(Description) quantity 
                    FROM sch_dta.t_value
                    GROUP BY Description)
SELECT sch_dta.t_Value.*, CTE_TEST.quantity 
FROM sch_dta.t_Value 
INNER JOIN CTE_TEST ON CTE_TEST.specID = sch_dta.t_Value.Id

И вот результат:

enter image description here

Надеюсь это поможет!

HK

Ответ 9

SELECT ProductID, ProductName, OrderQuantity, SUM(OrderQuantity) FROM OrderDetails WHERE(OrderQuantity) IN(SELECT SUM(OrderQuantity) FROM OrderDetails GROUP BY OrderDetails) GROUP BY ProductID, ProductName, OrderQuantity;

Я использовал вышеуказанное решение для решения аналогичной проблемы в Oracle12c.