how do i get the sum of the 4th column - sql

this statement will generate a 4 column table:
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM receipt
how do i get the total sum of the 4th of column of what the above generates?

I like to use subqueries for everything.
SELECT SUM(results.amount)
FROM
(
SELECT -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT amount
FROM
...
) results

SUM(-price*quantity)
huh?

Try
sum(price*quantity)
or combine both query as
SELECT badguy,rdate,notes,SUM(AMOUNT) FROM(
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM) A

Wrap your query in another query, where the outer query just gets the sum you want. This makes your query a subquery.
SELECT SUM(amount) FROM (
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM <...>
)

Related

Select columns together with the sum()

I have a problem in getting the columns and I also want to get the sum of total_amount.
CREATE TABLE purchase (
id int,
sheet_number varchar(255),
total_amount decimal(23,6),
transaction_status int
);
INSERT INTO purchase (id, sheet_number, total_amount, transaction_status)
VALUES (
'1', 'PO10010000001', '120.18', 1,
'2', 'PO10010000002', '87.23', 1,
'3', 'PO10010000003', '53.56', 3,
'4', 'PO10010000004', '150.28', 4,
'5', 'PO10010000005', '160.53' 3,
);
I want to get the columns and also the sum of this total_amount with respect (group by) of transaction_status.
I've created a SQL query like this but it doesn't work with the expected one.
Here is the SQL query that I've made:
SELECT
id,
sheet_number,
transaction_status,
sum(total_amount) AS total FROM purchase
GROUP BY transaction_status, id, sheet_number
I think the problem because I listed the other columns/attributes in the GROUP BY clause.
But I needed it because it will prompt an error message that the column is not valid since it is not contained in the group by clause.
The expected SQL query is like this (but I can't since there will be a prompt error):
SELECT
id,
sheet_number,
transaction_status,
sum(total_amount) AS total FROM purchase
GROUP BY transaction_status
The expected result will be:
[id],[sheet_number],[total],[transaction_status]
[1],[PO10010000001],[207.41],[1],
[2],[PO10010000002],[207.41],[1],
[3],[PO10010000003],[214.09‬],[3],
[4],[PO10010000004],[150.28],[4],
[5],[PO10010000005],[214.09‬],[3]
I just want to get all the same columns but I can get also the sum of total_amount.
You can use window function :
SELECT p.id, p.sheet_number, p.transaction_status,
SUM(p.total_amount) OVER (PARTITION BY p.transaction_status) AS total
FROM purchase p
ORDER BY p.id;
You can try the inner join to get the output as shown below.
Here I have taken total amount group by transaction status and done joining with actual table based on the transaction status column.
SELECT purchase.id
,purchase.sheet_number
,b.total AS total_amount
,purchase.transaction_status
FROM purchase
INNER JOIN (
SELECT transaction_status
,SUM(total_amount) AS total
FROM purchase
GROUP BY transaction_status
) b ON purchase.transaction_status = b.transaction_status
Here is the db<>fiddle demo.

SQL Nested Select -Subquery returned more than 1 value-

I have a table Sales with columns SalesID, SalesName, SalesCity, SalesState.
I am trying to come up with a query that only shows salesName where there is one SalesName per SalesCity. So for example, if SaleA is in Houston and SaleB is in Houston, SaleA and SaleB will not be returned.
select
SalesName, SalesCity, SalesState
from
Sales
where
(select count(*) from Sales group by SalesCity) = 1;
I am not entirely sure how to link the inner select back out. I need another column in the nested select to identify the SalesID. I am currently stuck and have made no progress.
You can get the names of cities that have only 1 sale by using GROUP BY and HAVING operators. Then use these results in your where clause:
SELECT SalesName, SalesCity, SalesState
FROM Sales WHERE SalesCity IN
(
SELECT SalesCity
FROM Sales
GROUP BY SalesCity
HAVING COUNT(SalesCity) = 1
)
You can do this without a subquery:
select MIN(SalesName) as SalesName, SalesCity, MIN(SalesState) as SalesState
from Sales
group by SalesCity
having count(*) = 1;
If there is only one row for the city, then the min() will return the value on that row.

subquery the same table in select statement

I have a resturant db and I need to total up the total value of all the items sold individually. So if I sold a hamburger that has a base price of $10.00 with bacon which costs $1.00 and a hambuger(again $10.00) with avacado that costs $0.50 I need to get $21.50 returned. My invoice table looks like this:
invoice_num item_num price item_id parent_item_id
111 hmbg 10.00 guid_1 ''
111 bacn 1.00 guid_2 guid_2
112 hmbg 10.00 guid_3 ''
112 avcd 0.50 guid_4 guid_3
I can get the sum of all the parent items like this:
SELECT item_num, SUM(price) FROM invoices WHERE parent_item_id = ''
it is the adding of the toppings that is confusing me. I feel like I need to add a subquery in the SUM but I'm not sure how to go about doing it and referencing the original query to use the item_id.
SELECT item_num, sum(i.price) + sum(nvl(x.ingred_price,0))
FROM invoices i
LEFT OUTER JOIN
(SELECT parent_item_id
, sum(price) ingred_price
FROM invoices
WHERE parent_item_id IS NOT NULL
GROUP BY parent_item_id) x
ON x.parent_item_id = i.item_id
WHERE i.parent_item_id IS NULL
GROUP BY item_num
Here's a SQL Fiddle that proves the above code works. I used Oracle, but you should be able to adapt it to whatever DB you are using.
Assumption: You don't have more than one level in a parent child relationship. E.g. A can have a child B, but B won't have any other children.
Not clear based on your question (see my comment) but as I understand it a simple group by will give you what you want. If not please explain (in the original question) why does this query does not work --- what is it missing from your requirements?
SELECT item_num, SUM(price)
FROM invoices
GROUP BY item_num
Hard to say, but looks like you need recursive cte.
Here's example for PostgreSQL:
with recursive cte as (
select
t.invoice_num, t.price, t.item_id, t.item_num
from Table1 as t
where t.parent_item_id is null
union all
select
t.invoice_num, t.price, t.item_id, c.item_num
from Table1 as t
inner join cte as c on c.item_id = t.parent_item_id
)
select invoice_num, item_num, sum(price)
from cte
group by invoice_num, item_num
sql fiddle demo
I've used null for empty parent_item_id (it's better solution than using empty strings), but you can change this to ''.

SQL: Using UNION

Here is the question and database info.
Use the UNION command to prepare a full statement for customer 'C001' - it should be laid out as follows. (Note that the values shown below are not correct.) You may be able to use '' or NULL for blank values - if necessary use 0.
Here is a link to the webpage with the database info. http://sqlzoo.net/5_0.htm or see the image below.
Here is what I have tried:
SELECT sdate AS LineDate, "delivery" AS LEGEND, price*quantity AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
UNION
SELECT rdate,notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
Here is what I get back:
Wrong Answer. The correct answer has 5 row(s).
The amounts don't seem right in the amount column and I can't figure out how to order the data by the date since it is using two different date columns (sdate and rdate which are UNIONED).
Looks like the data in the example is being aggregated by date and charge type using group by, that's why you are getting too many rows.
Also, you can sort by the alias of the column (LineDate) and the order by clause will apply to all the rows in the union.
SELECT sdate AS LineDate, "delivery" AS LEGEND, SUM(price*quantity) AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
GROUP BY sdate
UNION
SELECT rdate, notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
ORDER BY LineDate
It's usually easiest to develop each part of the union separately. Pay attention to the use of "null" to separate the monetary columns. The first select gets to name the columns.
select s.sdate as tr_date, 'Delivery' as type, sum((s.quantity * p.price)) as extended_price, null as amount
from shipped s
inner join product p on p.id = s.product
where badguy = 'C001'
group by s.sdate
union all
select rdate, notes, null, sum(amount)
from receipt
where badguy = 'C001'
group by rdate, notes
order by tr_date

Help with SQL View involving SUM function

I would like to get the following data (and more) into a single view.
SELECT Price FROM dbo.OrderItems WHERE OrderItemTypeId = 0
And
SELECT SUM (Price) AS ShippingTotal FROM dbo.OrderItems WHERE OrderItemTypeId = 1
I can’t seem to figure out how to do this with my weak SQL skills. Anybody know how I could do this?
You can use UNION statement:
SELECT Price FROM dbo.OrderItems WHERE OrderItemTypeId = 0
UNION
SELECT SUM (Price) AS ShippingTotal FROM dbo.OrderItems WHERE OrderItemTypeId = 1
But what is the semantic behind this ... In the first statement you have only one row with id = 0, in the second an aggregate function grouped by the same column (which suppose that there are more than one record with id=1). It will be helpful to show us the sample data for you table.
To improve your skills about UNION, see here: http://www.w3schools.com/sql/sql_union.asp
To cover all OrderItemTypeId...
SELECT OrderItemTypeId, SUM(Price) AS ShippingTotal
FROM dbo.OrderItems
GROUP BY OrderItemTypeId
One way would be like this:
SELECT Price, 0 AS OrderItemTypeId FROM dbo.OrderItems WHERE OrderItemTypeId = 0
UNION ALL
SELECT SUM(Price) AS Price, 1 AS OrderItemTypeId FROM dbo.OrderItems
WHERE OrderItemTypeId = 1
The 2nd column I've added to the results allows you to determine the different rows.