SUM () каждая отдельная строка с одинаковым идентификатором - PullRequest
0 голосов
/ 14 сентября 2018

Учитывая следующий запрос SQL:

SELECT orders.id, orders.shop_id,
       products.price * line_items.quantity as total_value,
       line_items.description, line_items.id as lineitem_id, 
       line_items.order_id, products.price as price,
       line_items.product_id, line_items.quantity
from orders
JOIN line_items 
    ON line_items.order_id = orders.id
JOIN products 
    ON line_items.product_id = products.id;

дает следующий результат:

sql query result

Я пытаюсь использоватьSUM(), чтобы сложить все столбцы price для одного и того же order_id и попробовал этот новый запрос:

SELECT orders.id, orders.shop_id, SUM(products.price),
        line_items.description, line_items.id as lineitem_id,
        line_items.order_id, products.price as price,
        line_items.product_id, line_items.quantity
from orders
JOIN line_items 
    ON line_items.order_id = orders.id
LEFT JOIN products 
    ON line_items.product_id = products.id
GROUP BY orders.id;

, который правильно работает (см. Ниже).

sql query result with SUM

Однако я все еще хочу сохранить каждую строку, как показано на первом изображении, И столбец total_value суммируется.

На первом изображении столбцы total_value для первой и второй строки (с order_id из 1) должны быть 2199.98 - возможно ли это?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Поверьте, вам нужно использовать подзапрос, чтобы достичь этого:

SELECT
    orders.id
  , orders.shop_id
  , tv.total_value
  , line_items.description
  , line_items.id  AS lineitem_id
  , line_items.order_id
  , products.price AS price
  , line_items.product_id
  , line_items.quantity
FROM orders
JOIN line_items ON line_items.order_id = orders.id
JOIN products ON line_items.product_id = products.id
JOIN (
    SELECT
        line_items.order_id
      , SUM(products.price * line_items.quantity) total_value
    FROM line_items
    LEFT JOIN products ON line_items.product_id = products.id
    GROUP BY
        line_items.order_id
    ) tv ON tv.order_id = orders.id

OR

используйте SUM() OVER(), если доступно

SELECT
    orders.id
  , orders.shop_id
  , SUM(products.price * line_items.quantity) over(partition by orders.id) total_value
  , line_items.description
  , line_items.id  AS lineitem_id
  , line_items.order_id
  , products.price AS price
  , line_items.product_id
  , line_items.quantity
FROM orders
JOIN line_items ON line_items.order_id = orders.id
JOIN products ON line_items.product_id = products.id
0 голосов
/ 14 сентября 2018

Я не уверен, какую СУБД или программное обеспечение базы данных вы используете, но вы можете рассмотреть здесь использование CTE или Common Table Expressions.Приведенный ниже метод WITH ... AS не работает с mySQL, но работает в Oracle, SQL Server, MariaDB или чем-то еще.Если вы используете mySQL, мы можем переписать его для правильной работы.

В идеале, вы собираетесь создать две временные таблицы.

  1. Первая временная таблица будет содержатьрезультаты вашего первого запроса
  2. Ваша вторая временная таблица будет содержать результаты вашего второго запроса
  3. Затем мы хотим объединить эти таблицы, чтобывсе, где order_id равен 1 или 2, возвращает общее значение для этого заказа [которое мы вычислили во втором запросе]
  4. В конечном счете, вы просто хотите выбрать правильные данные

Вот пример кода SQL, который должен работать, если вы не используете mySQL:

WITH firstQuery AS
(
    SELECT orders.id, orders.shop_id,
       products.price * line_items.quantity as total_value,
       line_items.description, line_items.id as lineitem_id, 
       line_items.order_id, products.price as price,
       line_items.product_id, line_items.quantity
from orders
JOIN line_items 
    ON line_items.order_id = orders.id
JOIN products 
    ON line_items.product_id = products.id;
),

secondQuery AS
(
    SELECT orders.id, orders.shop_id, SUM(products.price) as "total_price",
        line_items.description, line_items.id as lineitem_id,
        line_items.order_id, products.price as price,
        line_items.product_id, line_items.quantity
from orders
JOIN line_items 
    ON line_items.order_id = orders.id
LEFT JOIN products 
    ON line_items.product_id = products.id
GROUP BY orders.id;
)

SELECT
    firstQuery.*,
    total_price
FROM
    firstQuery LEFT JOIN secondQuery ON firstQuery.order_id = secondQuery.order_id

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

Он чрезвычайно мощный и, безусловно, дает вам невероятные способности, когда дело доходит до данных и аналитики.

Дайте мне знать, если это работает для вас, если нет, мы можем работать через него ииспользуйте CTE по-другому:)

ОБНОВЛЕНИЕ - видел, что вы упоминали, что используете SQLite.Это должно работать там.Вот хороший обзор того, что мы достигаем, используя подзапросы в простом формате: https://www.sqlite.org/lang_with.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...