简体   繁体   中英

SELECT a column and SUM() of values from another table in SQL

I'm pretty new with SQL, and this is giving me trouble. The idea is that I have several tables. Here are the relevant tables and columns:

customers:

customer_id, customer_name


orders:

order_id, customer_id


orderline:

order_id, item_id, order_qty


items:

item_id, unit_price

I need to return customer_name as well as total revenue from that customer (calculated as item_price * order_qty * 2).

Here's what I have written:

SELECT customers.customer_name, sum(revenue)
    FROM SELECT orderline.order_qty * items.unit_value * 2 AS revenue
        FROM orderline
            INNER JOIN orders
            ON orderline.order_id = orders.order_id
    INNER JOIN customers
        ON revenue.customer_id = customers.customer_id;

This throws a syntax error and I'm not really sure how to proceed.

This is only one example of this type of problem that I need to work out, so more generalized answers would be helpful.

Thanks in advance!

EDIT:

With help from answers I ended up with this code, which just gets total revenue and puts it next to the first person in the DB's name. What did I get wrong here?

SELECT customers.customer_name, sum(revenue)
    FROM(SELECT orderline.order_qty * items.unit_price * 2 AS revenue, orders.customer_id AS CustomerID
        FROM( orderline
            INNER JOIN orders
            ON orderline.order_id = orders.order_id
                INNER JOIN items
                ON orderline.item_id = items.item_id)) CustomerOrders
    INNER JOIN customers
        ON CustomerOrders.CustomerID = customers.customer_id;
SELECT c.customer_name, 
       sum(COALESCE(ol.order_qty,0) * COALESCE(i.unit_value,0) * 2)
FROM customers c
INNER JOIN orders o
ON o.customer_id = c.customer_id;
INNER JOIN orderline ol
ON ol.order_id = o.order_id
INNER JOIN items i
ON i.item_id = ol.item_id
GROUP BY c.customer_id

A couple issues with your query. First, you need to scope your subquery and alias it:

(SELECT orderline.order_qty * items.unit_value * 2 AS revenue
    FROM orderline
        INNER JOIN orders
        ON orderline.order_id = orders.order_id) CustomerOrders

Secondly, you need to select more than the revenue in the subquery since you are joining it to your customers table

(SELECT 
    orderline.order_qty * items.unit_value * 2 AS revenue,
    orders.customer_id AS CustomerId
FROM 
    orderline
INNER JOIN orders ON orderline.order_id = orders.order_id) CustomerOrders

Then you need to use the subquery alias in the join to the customers table and wrap it all up in a group by customer_id and CustomerOrders.Revenue

I would tend to do it differently. I'd start with selecting from the customer table, because that is the base of what you are looking for. Then I'd do a cross apply on the orders that would all aggregating the order revenue in the subquery. It would look like this (tsql, you could do the same in mysql with a join with some aggregation):

SELECT
    customers.customer_name,
    ISNULL(customerOrders.Revenue, 0) AS Revenue
FROM
    customers
OUTER APPLY (
    SELECT
        SUM (orderline.order_qty * items.unit_value * 2) AS Revenue
    FROM
        orders
    INNER JOIN
        orderline ON orders.order_id = orderline.order_id
    INNER JOIN
        items on orderline.item_id = items.item_id
    WHERE
        orders.customer_id = customers.customer_id
) CustomerOrders

In this case, the subquery aggregates all your orders for you and only returns one row per customer, so no extraneous returned data. Since it's an outer apply, it will also return null for customers with no orders. You could change it to a CROSS APPLY and it will filter out customers with no orders (like an INNER JOIN).

select customer_name, sum(item_price * order_qty * 2) as total_revenue
from (
  select * from customers
  inner join orders using(customer_id)
  inner join orderline using(order_id)
  inner join items using(item_id)
)
group by customer_name
select
    c.customer_name,
    r.revenue
from
    customers c
inner join 
    orders ord on
    ord.customer_id = c.customer_id
inner join
    (select i.item_id, o.order_id, sum(o.order_qty * items.unit_value * 2) as revenue
    from orderline o
    inner join items i on
    i.item_id = o.item_id
    group by o.order_id, i.item_id) as r on r.order_id = o.order_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM