Issue to get total amount while using inner join in MYSQL - mysql

I get an wrong TotalPrice from the ItemDetails table while join the taxdetails table.
Code 1:
select Distinct B.ID as BillId,
I.ID as ItemDetailId,
I.TotalPrice as ItemPrice,
T.Amount as TaxAmount from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id;
Refer below image,
While sum the TotalPrice and TotalTaxAmount on the same query i got an wrong TotalPrice result,
Code 2:
select Distinct B.ID as BillId,
SUM(I.TotalPrice) as TotalPrice,
SUM(T.Amount) as TotalTaxAmount from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id
group by B.ID;
Please refer below image,
Actual issue is as per taxdetails per itemdetail each row the rows become multiple so the totalprice get differs.
Expected Output for code 2 (i have listed the first row expected result) is,
Billid TotalPrice TotalTaxAmount
1 70 30

Try this,you have multiple items/bill, that is why you can't make inner join directly.Remove group by also.
select B.ID as BillId,
I.TotalPrice as TotalPrice,
T.Amount as TotalTaxAmount from Bill B
inner join
(
select BillNoID,SUM(TotalPrice) as TotalPrice from ItemDetails
group by BillNoID
)as I on I.BillNoID = B.ID
inner join
(
Select ItemDetailId,SUM(Amount) as Amount from TaxDetails
group by ItemDetailId
)as T on T.ItemDetailId = I.Id

Related

How can I select the second minimal value within a inner join?

I have this query
select c.id, c.name, c.email, c.totalpets, min(p.date_created) as first_order,
min(p.weight) as min_weight_bought,
max(p.weight) as max_weight_bought,
count(p.ordernumber) as total_orders
from orders p
inner join customers c
on p.customer_id = c.id
where p.approved = 1
and c.totalpets >= 1
group by c.id
having total_orders > 1
Note that first_order gives me the first result of the row, right? I am trying to get customer first order and customer second order. How can i do that within this inner join?
Thanks
SELECT c1.id,
c1.name,
c1.email,
c1.totalpets,
p1.date_created
FROM orders p1
INNER JOIN customers c1
ON p1.customer_id = c1.id
WHERE
(
SELECT COUNT(*)
FROM orders p2
INNER JOIN customers c2
ON p2.customer_id = c2.id
WHERE c2.id = c1.id AND p2.date_created <= p1.date_created
) <= 2
ORDER BY c1.id;
Here is a running demo which shows a simplified version of the above query (and simplified data set) in action:
SQLFiddle

SQL: Sum factor*value in a LEFT JOIN

I would like to get some information: I got a table called "invoices" and a table called "invoice_positions".
All personal information about a customer are stored in "invoices". All positions are stored in "invoice_positions".
Well, now I would like to know the total sum of all matching positions:
I got this invoice-entry:
id: 1
customer: 4
I got this invoice-positions-entry:
id: 1
invoiceid: 1
factor: 2
value: 5
id: 2
invoiceid: 1
factor: 1
value: 5
The result should be: 2*5+1*5 = 15
This is my query so far:
SELECT DISTINCT a.*,SUM(ip.factor * ip.value) as totalsum,om.orderid,o.userid as userid,c.lastname as customer_lastname, c.firstname as customer_firstname, c.company as customer_company,uc.name AS editor,created_by.name AS created_by
FROM `o45_hero_invoices` AS a
LEFT JOIN o45_hero_invoices_positions AS ip ON ip.invoiceid=a.id
LEFT JOIN o45_hero_invoices_mapping AS om ON om.invoiceid=a.id
LEFT JOIN o45_hero_orders AS o ON o.id=om.orderid
LEFT JOIN o45_hero_customers AS c ON c.userid=o.userid
LEFT JOIN o45_users AS uc ON uc.id=a.checked_out
LEFT JOIN o45_users AS created_by ON created_by.id = a.created_by
WHERE (a.state IN (0, 1))
ORDER BY a.id asc
But my result is not 15 - it's 30.
you will no longer need the distinct with the group by.
a.* will have to be split into individual columns you want to return in results.
group by has been added below for known columns
.
SELECT a.*,SUM(ip.factor * ip.value) as totalsum,
om.orderid, o.userid as userid, c.lastname as customer_lastname,
c.firstname as customer_firstname, c.company as customer_company,
uc.name AS editor,
created_by.name AS created_by
FROM `o45_hero_invoices` AS a
LEFT JOIN o45_hero_invoices_positions AS ip ON ip.invoiceid=a.id
LEFT JOIN o45_hero_invoices_mapping AS om ON om.invoiceid=a.id
LEFT JOIN o45_hero_orders AS o ON o.id=om.orderid
LEFT JOIN o45_hero_customers AS c ON c.userid=o.userid
LEFT JOIN o45_users AS uc ON uc.id=a.checked_out
LEFT JOIN o45_users AS created_by ON created_by.id = a.created_by
WHERE (a.state IN (0, 1))
GROUP BY a.Field1, a.Field2, A.Field3...,
om.orderid, o.userid, c.lastname, c.firstname,
c.company, uc.name, created_by.name
ORDER BY a.id asc

MySQL One-To-Many SUM of COUNTs

After 2 days of searching and trying similar questions, it's got to the point where I need to ask the question!
I have the following database structure (simplified)..
mt_product | mt_sku | mt_price
========== | ====== | ========
id | brand_id | mpn | id | product_id | retailer_id | sku | id | sku_id | price | date
For instance...
* A can of Coca-Cola is ONE product.
* It can be sold in many different retailers, who will all have a SKU for it.
* This SKU will have a price, which can change day-by-day.
I want to list the total number of prices for the product.
To list this I currently have the following query which nearly works...
SELECT
p.id AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
(SELECT COUNT(s.id) FROM mt_sku AS s WHERE s.pid = p.id) AS num_sku,
(SELECT COUNT(gbp.id) FROM mt_price AS gbp INNER JOIN mt_sku ON mt_sku.id = gbp.sid ) AS num_price
FROM mt_product AS p
INNER JOIN mt_brand b ON p.bid = b.id
INNER JOIN mt_sku s ON p.id = s.pid
num_sku returns as expected, however when I introduce the second sub query for num_price (and I have revised this many times) I either get...
* no duplications of the pid but the num_price is the total number of prices to SKUs, not the amount of prices for this product_id (as query above) eg1_img
* the correct number of num_price, but instead of totalling up the total num_price, the pid is duplicated in the table (as query below) - therefore as the pid is duplicated, this does not give me the result I want. I added DISTINCT as it helped an earlier version of the query, it now makes no difference. eg2_img
SELECT
DISTINCT(p.id) AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
(SELECT COUNT(s.id) FROM mt_sku AS s WHERE s.pid = p.id) AS num_sku,
(SELECT COUNT(gbp.id) FROM mt_price AS gbp WHERE s.id = gbp.sid) AS num_price
FROM mt_product AS p
INNER JOIN mt_brand b ON p.bid = b.id
INNER JOIN mt_sku s ON p.id = s.pid
I'm pretty sure the key to this is that
product can have multiple SKUs, of which a SKU has multiple price history.
Any help or ideas of the schema would be superb.
Try this:
SELECT
p.id AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
COUNT(DISTINCT s.id) AS num_sku,
COUNT(gbp.id) AS num_price
FROM mt_product AS p
INNER JOIN mt_brand b ON p.brand_id = b.id
INNER JOIN mt_sku s ON p.id = s.product_id
INNER JOIN mt_price gbp ON s.id = gbp.sku_id
GROUP BY b.id, p.id
The products that don't have SKUs defined will not appear in the result set. Use LEFT JOIN mt_sku to make them appear in the result set (having 0 for num_sku and num_price):
LEFT JOIN mt_sku s ON p.id = s.product_id
In both variants of the query, the products that do not have prices defined will not appear in the result set. Use LEFT JOIN mt_price to include them into the result set (having 0 for num_price):
LEFT JOIN mt_price gbp ON s.id = gbp.sku_id
Take a look at the MySQL documentation for JOINs, GROUP BY and GROUP BY aggregate functions.
If you want to list the total prices then you need correlations.
Your first count is fine, because it is correlated to the outer query. The second has no correlation, so that seems strange. The following fixes the num_price subquery:
SELECT p.id AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
(SELECT COUNT(s2.id) FROM mt_sku s2 WHERE s2.pid = p.id) AS num_sku,
(SELECT COUNT(gbp.id) FROM mt_price gbp WHERE s.id = gbp.sid ) AS num_price
FROM mt_product p INNER JOIN
mt_brand b
ON p.bid = b.id INNER JOIN
mt_sku s
ON p.id = s.pid;
I'm also not sure why you have all the joins in the outer query. I assume that a given product is going to have multiple rows, and you want the multiple rows to have the same num_sku and num_price values.

Issue while Combining multiple rows in MySQL

I want to build the query according to the following conditions,
I just want to combine the sum the Total price of both type 1 and type 2.
Combine 2 rows into 1 and avoid null values in that rows.
Query,
select B.ID as BillId,
I.Id as ItemID,
t.Type,
SUM(I.TotalPrice) as TotalPrice,
Case when t.Type = 1 then SUM(T.Amount) end as TaxAmountType1,
Case when t.Type = 2 then SUM(T.Amount) end as TaxAmountType2
from Bill B
inner join ItemDetails I
on I.BillNoID = B.ID
inner join TaxDetails T
on T.ItemDetailId = I.Id
group by
B.ID,
I.Id,
I.TotalPrice,
t.Type;
Please refer below image,
Expected Output:
'1', '1', NULL, '40.00', '3.00', '5.00'
Note:
1. I dont want to use sub-query.
2. Expected output "NULL" refers i don't want to show that column seperately.
Sounds like this would solve your problem. If not please give more informations.
SELECT B.ID as BillId, I.Id as ItemId,
t.type, SUM(TotalPrice), SUM(TaxAmountType1),
SUM(TaxAmountType2)
FROM Bill B
GROUP BY BillId, ItemId, t.type
Don't group by the column that you're trying to aggregate. Remove the I.TotalPrice from the GROUP BY:
select B.ID as BillId, I.Id as ItemID, t.Type, SUM(I.TotalPrice) as TotalPrice,
Case when t.Type = 1 then SUM(T.Amount) end as TaxAmountType1,
Case when t.Type = 2 then SUM(T.Amount) end as TaxAmountType2 from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id
group by B.ID, I.Id, t.Type;`
Try
select B.ID as BillId, I.Id as ItemID, null as Type, SUM(I.TotalPrice) as TotalPrice,
Case when t.Type = 1 then SUM(T.Amount) end as TaxAmountType1,
Case when t.Type = 2 then SUM(T.Amount) end as TaxAmountType2
from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id
group by B.ID, I.Id, I.TotalPrice
You don't want to group by type, that's the issue (you also can remove the ", null as Type" from the select)
If you group by t.type, you wont be able to have those instances in the same line.
Try:
select B.ID as BillId, I.Id as ItemID, t.Type, SUM(I.TotalPrice) as TotalPrice,
Case when t.Type = 1 then SUM(T.Amount) end as TaxAmountType1,
Case when t.Type = 2 then SUM(T.Amount) end as TaxAmountType2 from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id
group by B.ID, I.Id, I.TotalPrice;

Incorrect id returned on LEFT JOIN in Mysql statement

I need to get the id and timestamps of table sellers and all other columns (without knowing the column names) from these results returned from this MySql statement:
SELECT * FROM sellers a
LEFT JOIN users b ON a.user_id = b.id
LEFT JOIN country_types c ON a.country_type_id = c.id
LEFT JOIN language_types d ON a.language_type_id = d.id
WHERE a.email=?
The seller id though is incorrectly set because users, country_types, and language_types all have a value id. How can I set seller_id and seller_timestamp? I tried this but it is incorrect:
SELECT a.id seller_id, a.timestamp seller_timestamp, * FROM sellers a ...
You want this:
SELECT a.id as seller_id, a.timestamp as seller_timestamp, a.*, b.*, c.*, d.*
FROM sellers a
LEFT JOIN users b ON a.user_id = b.id
LEFT JOIN country_types c ON a.country_type_id = c.id
LEFT JOIN language_types d ON a.language_type_id = d.id
WHERE a.email=?
Im not sure but try alias, for example:
a.id AS seller_id
and etc.
In joins you can't select other columns in this way:
SELECT a.id seller_id, a.timestamp seller_timestamp, * FROM sellers a...
You need to write required column names.