This is my DB structure:
Invoice
ID
Company
InvoiceLine
LineID
Quantity
Price
These are my rows:
Invoice
ID Company
1 XYZ
2 ZYX
InvoiceLine
LineID InvoiceID quantity price
1 1 1 10
2 1 5 10
3 2 1 20
What I'm trying to generate is to select my total invoice price dynamically:
IDEAL RESULT
1 XYZ 60
2 ZYX 20
I use the following query for this:
select ID, cil.quantity * cil.unitPrice as invoiceTotal from Invoice ci
join InvoiceLine as cil on ci.invoiceID = cil.invoiceID
Problem is that this query returns 2 rows for the first invoice.
Why is this and what how could I select ALL values of my invoice lines?
You want group by:
select ci.id, sum(cil.quantity * cil.unitPrice) as invoiceTotal
from Invoice ci join
InvoiceLine cil
on ci.invoiceID = cil.invoiceID
group by ci.id;
However, you don't even need the join:
select cil.id, sum(cil.quantity * cil.unitPrice) as invoiceTotal
from InvoiceLine cil
group by cil.id;
select Invoice.id,Invoice.Company sum(InvoiceLine.quantity * InvoiceLine.unitPrice) as TotalSum
from Invoice join
InvoiceLine cil
on Invoice.invoiceID = InvoiceLine.invoiceID
group by Invoice.id,Invoice.Company
order by Invoice.Company ;
Related
I have the following tables:
invoice
id
customerId
date
1
3
2020-10-10
2
NULL
2020-09-10
3
1
2020-10-15
product
id
name
price
1
car
10
2
pen
5
3
laptop
6
4
table
2
customer
id
name
1
a
2
b
3
c
4
d
invoceProduct
id
invoiceid
productid
1
1
1
3
1
2
4
1
4
5
2
2
6
2
3
I need to get the following for each invoice:
invoiceID, date, customerName, Total, Quantity(count of items), max product name and price, min product name and price in each invoice.
I wrote query and get most of values but I cannot get the name of products.
This is my sql query
WITH cte_Products(InvoiceId, date, CustomerName, ProductName, price) AS
(
select
i.id as InvoiceId,
i.date as date,
CASE
when c.name IS NULL THEN 'NoName'
Else c.name
End AS CustomerName,
p.name as ProductName,
p.price as price
from invoceProduct ip
join product p on p.id = ip.productID
join invoice i on i.id = ip.invoiceId
left join customer c on i.customerId = c.id
)
select
cte.InvoiceId,
cte.date,
cte.CustomerName,
SUM(cte.price) as Total,
count(*) AS ItemsQuantity,
MAX(cte.price) AS MostExpensiveItem,
MIN(cte.price) AS CheapestItem
from
cte_Products cte
group by cte.InvoiceId, cte.date, cte.CustomerName;
I got this result
InvoiceId
date
CustomerName
Total
ItemsQuantity
MostExpensiveItem
CheapestItem
1
2020-10-10
c
17
3
10
2
2
2020-09-10
NoName
11
2
6
5
I need to add the product name with product price under MostExpensiveItem and CheapestItem.
I am working on two tables
PRODUCT table
with
PRODUCTID, PRICE
and I am working with
ORDERLINE table
which has
PRODUCTID, QUANTITY, ORDERID
I want to join both tables so that I have
ORDERQUANTITY
which has
PRODUCT.PRODUCTID, ORDERLINE.QUANTITY
GROUPED BY
PRODUCTID
In other words I would like the two tables not to be like this:
PRODUCTID QUANTITY
- 10 4
- 10 2
- 20 1
- 20 6
- 30 4
- 30 6
- 30 2
- 30 2
- 40 2
- 40 2
- 40 5
But like this
PRODUCTID QUANTITY
- 10 6
- 20 7
- 30 14
- 40 9
My current code shown below only does the first table when I try to group by productid it won't work.
SELECT PRODUCT.PRODUCTID, ORDERLINE.QUANTITY
FROM ORDERLINE
FULL OUTER JOIN PRODUCT ON PRODUCT.PRODUCTID = ORDERLINE.PRODUCTID
ORDER BY PRODUCT.PRODUCTID;
You don't need the join if you need only id and sum of ordered quantity :
select PRODUCTID, sum(QUANTITY)
from ORDERLINE
group by PRODUCTID
order by PRODUCTID;
I think a simple SUM aggregate function and GROUP BY query will be enough:
SELECT PRODUCT.PRODUCTID, coalesce( SUM( ORDERLINE.QUANTITY), 0 )
FROM ORDERLINE
FULL OUTER JOIN PRODUCT ON PRODUCT.PRODUCTID = ORDERLINE.PRODUCTID
GROUP BY PRODUCT.PRODUCTID
ORDER BY PRODUCT.PRODUCTID;
I'm not sure about understanding your question, but I think that this sentece should give you the results you are asking for:
SELECT PRODUCT.PRODUCTID, SUM(ORDERLINE.QUANTITY) AS QUANTITY
FROM ORDERLINE
FULL OUTER JOIN PRODUCT ON PRODUCT.PRODUCTID = ORDERLINE.PRODUCTID
GROUP BY PRODUCT.PRODUCTID
ORDER BY PRODUCT.PRODUCTID;
SELECT PRODUCT.PRODUCTID, SUM(ORDERLINE.QUANTITY)
FROM ORDERLINE
FULL JOIN PRODUCT ON PRODUCT.PRODUCTID = ORDERLINE.PRODUCTID
GROUP BY PRODUCT.PRODUCTID
Here it is in action: SQL Fiddle
I have these tables in my postresql:-
1.Payment(id, number, amount)
2.Invoice(id, number, amount)
and a invoice_payment table to allocate payments amount to invoices
3.InvoicePayment(id, payment_id, invoice_id, amount)
Single payment can be allotted to many invoices.
Now I want payment details, but I also want invoices.number of the invoices this payment is allotted to. I am doing something like this:-
SELECT
payments.number,
payments.amount,
(SELECT invoices.number from invoices INNER JOIN invoice_payments
ON invoices.id = invoice_payments.invoice_id
WHERE invoice_payments.payment_id = payments.id)
from payments
But it gives me error more than one row returned by a subquery. How do I make the invoice number comma-seperated for every payments row?
Sample data:-
Payment
id number amount
1 "Pay001" 100
2 "Pay002" 150
3 "Pay003" 150
Invoice
id number amount
1 "INV001" 100
2 "INV002" 200
3 "INV003" 100
InvoicePayment
id payment_id invoice_id amount
1 1 1 50
2 1 2 50
3 2 2 150
4 3 1 50
5 3 3 100
Result:-
payment_id payment_number amount invoices
1 "Pay001" 100 "INV001, INV002"
2 "Pay002" 150 "INV002"
3 "Pay003" 150 "INV001, INV002"
You can use string_agg function in postgres to concatenate rows, separated by chosen delimiter.
SELECT
payments.number,
payments.amount,
(SELECT string_agg(invoices.number,',') from invoices INNER JOIN invoice_payments
ON invoices.id = invoice_payments.invoice_id
WHERE invoice_payments.payment_id = payments.id)
from payments
Try this
SELECT
payments.number,
payments.amount,
inv_p.inv_no
from payments p inner join (Select invoice_payments.payment_id, string_agg(invoices.number,',') as inv_no
From invoices inner join invoice_payments on (invoices.id = invoice_payments.invoice_id)
Group by invoice_payments.payment_id) inv_p on (p.id = inv_p.payment_id)
Here I Have Two tables:
Orders
OrderId OrderName
1 Apple
2 Mango
Cust
Id Name OrderId Price
1 John 1 50
2 John 1 100
3 Mic 1 10
4 Mic 2 10
Sql Join Query:
SELECT Orders.CustName,Items.IteamName,Orders.Price
FROM Orders JOIN Items ON Items.Id = Orders.Id
Group By
SELECT Orders.CustName, SUM(Price) FROM Orders GROUP BY Orders.CustName
How can I Write Group by in Join?
You can do like this:
Select Orders.CustName, Items.IteamName, SUM(Orders.Price)
FROM
Orders JOIN Items ON Items.Id=Orders.Id
GROUP BY
Orders.CustName, Items.IteamName
The fields that you doesn't aggregate you put at the GROUP BYclause.
i have 3 tables Product Category and ProductCategory.
Product table:
ProductID ProductName
1 P1
2 P2
3 P3
Category table:
CategoryID CategoryName
1 C1
2 C2
3 C3
ProductCategory:
ProductID CategoryID
1 1
1 2
1 3
2 3
3 1
3 2
I need a query which returns products which fall under more than 1 categories. Based on the table data above the result would be:
ProductID ProductName
1 P1
3 P3
So i wrote a query to fetch all the ProductID's which have more than one CategoryID's as below:
select ProductID,count(CategoryID)
from ProductCategory
group by Productid
having count(CategoryID)>1)
But when i try to display product details using the below query i get an error:
select *
from Product
where ProductID in (
select ProductID,count(CategoryID)
from ProductCategory
group by Productid
having count(CategoryID)>1))
Is my query wrong? How do i get the required product details which fall in more than one categories?
Remove the COUNT() in the subquery. The result of the subquery when used on IN clause must have only one returned column.
SELECT *
FROM Product
WHERE ProductID IN
(
SELECT ProductID
FROM ProductCategory
GROUP BY Productid
HAVING count(CategoryID) > 1
)
SQLFiddle Demo
or by using JOIN
SELECT a.*
FROM Product a
INNER JOIN
(
SELECT ProductID
FROM ProductCategory
GROUP BY Productid
HAVING count(CategoryID) > 1
) b ON a.ProductID = b.ProductID
SQLFiddle Demo
You can try use CROSS APPLY Operator in SQL Server
SELECT DISTINCT C.ProductID,C.ProductName,A.CategoryID,A.Total
FROM Product C
CROSS APPLY (
Select CA.CategoryID,Total=COUNT(*)
From ProductCategory CA
Where C.ProductID=CA.ProductID
Group By CA.CategoryID Having COUNT(*)>1
) AS A
ORDER BY A.Total DESC
Take a look: http://explainextended.com/2009/07/16/inner-join-vs-cross-apply/