MS Access multiple joins with criteria - sql

I'm generating an Inventory Query and the below code (mostly) works but it includes Invoices that have been voided, resulting in negative inventory.
Void Yes/No field = tblInvoices.Void
tblInvoiceDetails.InvoiceNum = tblInvoices.ID
I can't figure out how to ensure this does not include invoices that were voided. Thank you in advance for your help!
SELECT tblInventory.ID, Nz(sumTotalPaid,0)-Nz(sumCreditAmount,0) AS Quantity
FROM (tblInventory
LEFT JOIN (
SELECT ProductID, Sum(Quantity) AS sumTotalPaid
FROM tblOrderDetails
GROUP BY tblOrderDetails.ProductID
) AS sum1
ON tblInventory.ID = sum1.ProductID)
LEFT JOIN (
SELECT ProductID, Sum(Quantity) AS sumCreditAmount
FROM tblInvoiceDetails
GROUP BY tblInvoiceDetails.ProductID
) AS sum2
ON tblInventory.ID = sum2.ProductID;

Try it this way:
SELECT tblInventory.ID, Nz(sumTotalPaid,0)-Nz(sumCreditAmount,0) AS Quantity
FROM (tblInventory
JOIN (
SELECT ProductID, Sum(Quantity) AS sumTotalPaid
FROM tblOrderDetails
GROUP BY tblOrderDetails.ProductID
) AS sum1
ON tblInventory.ID = sum1.ProductID)
JOIN (
SELECT ProductID, Sum(Quantity) AS sumCreditAmount
FROM tblInvoiceDetails
WHERE tblInvoiceDetails.InvoiceNum IN
(SELECT tblInvoices.ID
FROM tblInvoices
WHERE tblInvoices.Void='Yes')
GROUP BY tblInvoiceDetails.ProductID
) AS sum2
ON tblInventory.ID = sum2.ProductID
1.- First you use just JOIN instead of LEFT JOIN, so you just get the rows that have values in both tables.
2.- You get only the Products that have the tblInvoices.Void='Yes'

Related

How to find the earnings from the most sold product with sql?

I have two tables:
I need to find the product name that was sold the most and the earnings from that.
The code I wrote:
SELECT *
FROM Products
WHERE ProductId = (SELECT ProductId
FROM
(SELECT
ProductId,
SUM(Quantity) AS total_order,
MAX(SUM(Quantity)) OVER () AS maxSm
FROM
Orders
GROUP BY
ProductId)
WHERE
total_order = maxSm)
But with this I just find the product name that was sold the most. Can you tell me please how can I find the earnings only from this product?
select top 1
a.name,
(b.total * a.price) as revenue
from
products a
left join (select productid, sum(quantity) as total group by productid) b
on a.productid = b.productid
order by
b.total desc
You need to join the result of your derived table to your Products table.
Without actual sample data I am unable to test, however the following should be what you need, or at least very close:
select p.Name, o.total_order, o.total_order * p.Price as TotalValue
from (
select * from (
select ProductId,
Sum(Quantity) as total_order,
Max(Sum(Quantity)) over () as maxSm
from Orders
group byProductId
)t
where total_order = maxSm
)o join Products p on p.ProductId=o.ProductId

Select Sold and unsold product from same table in SQL Server for last month

I have Database table and trying to write query to find sold and not sold product list from one table.
Table is Below
Expecting Result
How do i get this result? i am using CTE to create Tamp table and with all services and then do left join but it dose give me only product sold in Feb, but i want all product with no sell too.
You can cross join the products and the dates, and then bring the table with a left join:
select
p.product,
t.quantity_sold,
d.yr,
d.mn
from (select distinct product from mytable) p
cross join (select distinct yr, mn from mytable) d
left join mytable t
on t.product = p.product
and t.yr = d.yr
and t.mn = d.mn
This puts nulls for rows with no sale - that's presumably a numeric column so you generally don't want to write a string like 'Not Sold' into it.
If there is a possibility of duplicate (product, yr, mn), you might want to use outer aggregation:
select
p.product,
sum(t.quantity_sold) quantity_sold,
d.yr,
d.mn
from (select distinct product from mytable) p
cross join (select distinct yr, mn from mytable) d
left join mytable t
on t.product = p.product
and t.yr = d.yr
and t.mn = d.mn
group by p.product, d.yr, d.mn

How can I get sum of Items from one table to another in Sql

How can I get sum of items from one table to another in sql
use join and subquery
select p.*,stock from theProduct p
join ( select prodcode,sum(Qty) as stock from thePurchaseDetail group by prodcode) t
on p.prodcode=t.prodcode
You can use APPLY :
select p.*, pp.stock
from theProduct p cross apply
(select sum(pp.qty) as stock
from thePurchaseDetail pp
where pp.prodcode = p.prodcode
) pp;
You can also use window function with JOIN :
select p.*, sum(pp.qty) over (partition by p.prodcode) as stock
from theProduct p inner join
thePurchaseDetail pp
on pp.prodcode = p.prodcode;
You would left join in case there are missing prodcodes in tblPurchaseDetail table
select p.*
,t.stock
from tblProduct p
left join ( select prodcode
,sum(Qty) as stock
from tblPurchaseDetail
group by prodcode
) t
on p.prodcode=t.prodcode

use IN statement within ID column and retrieve count(*)?

I have the following SQL command:
SELECT * from products
WHERE id IN (
SELECT product_id, count(*)
FROM account_products
GROUP BY product_id
)
obviously it doesnt retrieve any data, because the internal query retrieves two columns (product_id and count).
But I need the count too, because I'm gonna use it to make some math later.
How can I use this IN query using the count(*) too?
Thanks!
Join them:
select products.*, t.product_count
from products
join (
SELECT product_id, count(*) as product_count
FROM account_products
GROUP BY product_id
) as t on t.product_id = products.id
select products.*, count( account_products.product_id)
from products join account_products on
products.product_id = products.id
group by products.* (obviously all products-fields)
Or with a subquery in the select clause, when your DBMS supports it:
SELECT
products.*,
(SELECT count(*) FROM account_products ap WHERE ap.product_id = products.id) as "Number of Accounts"
from products
This might work for you:
WITH MyAccountProducts AS
(
SELECT product_id, count(*) AS CountOfAccountProducts
FROM account_products
GROUP BY product_id
)
SELECT p.*,ap.CountOfAccountProducts
from products AS p
INNER JOIN MyAccountProducts AS ap ON p.id=ap.product_id

SQL nested aggregate grouping error

I'm trying to find name of product which has sold maximum units, I've two tables, purchases and products, products has pname and pid, purchases has pid, qty(units sold).
I've managed this
select p.pname, sum(q.qty) from purchases q
inner join products p on p.pid=q.pid
where p.pid=q.pid
group by p.pname
order by sum(q.qty) desc
I'm getting the result in descending order but I need only the top most selling units, multiple products can have top most selling units. When I use
max(sum(q.qty))
I get grouping error.
One approach is to derive the values first using a common table expression.
Simply put you can't wrap aggregates in other aggregates. You may be able to wrap an aggregate around an analytic however.
with cte as (select p.pname, sum(q.qty) from purchases q
inner join products p on p.pid=q.pid
where p.pid=q.pid
group by p.pname
order by sum(q.qty) desc)
Select pname, max(purchases)
from cte
group by pname
You can use ctes to do this.
1)First get the total quantity of each product
2)Then get the maximum of all those totals
3)Join it with your original query
with totals as (select pid, sum(qty) totalqty from purchases group by pid)
, t1 as (select p.pid, p.pname, sum(q.qty) totqty
from purchases q
inner join products p on p.pid=q.pid
group by p.pname)
, t2 as (select max(totalqty) maxtotal from totals)
select pname, totqty
from t1
join t2 on t1.totqty = t2.maxtotal
Analytics can simplify this for you. If you have more than one product with the same sum(qty) and that happens to be the max(sum(qty)), then this should get you them:
select pname, quantity
FROM (
select p.pname
, sum(q.qty) quantity
,rank() over (order by sum(q.qty desc) ranking
from purchases q
inner join products p on p.pid=q.pid
group by p.pname
)
where ranking = 1