SUM function summing records twice - mysql

First of all for you to understand my question I need to show you my DB model, so here it is.
Now that you have seen it, here goes my question:
I have this query
select SUM(e.totalEtapa) totalProyecto,
e.idProyecto
from Etapa e
inner join EtapaPartida ep on ep.idEtapa = e.idEtapa
inner join Partida p on p.numero = ep.idPartida
and p.version = ep.versionPartida
left join Partida b on b.numero = p.numero
and p.version < b.version
inner join LineaRecursoPartida lrp on p.numero = lrp.numPartida
and p.version = lrp.versionPartida
inner join LineaRecurso lr on lr.id = lrp.IdLinea
inner join Recurso r on r.codigo = lr.codigo
and r.version = lr.version
where r.codigo = 2
and r.version = 2
and b.version is null
group by e.idProyecto
So as you can see, and in relation you the model I show you above, I want the sum of all the records on etapa that are related to a recurso's record taking into account all the join necessary to get to it and that the partida's records should be their "maximun versions", in this case the recurso with codigo = 2 and version = 2. So the thing is this query is returning twice the value that should. Making some research I realized that this is happening because my recurso's record is related to two records on partida's table and likewise this ones are related to the same etapa's record through the EtapaPartida table.
I already tried using the distinct clause, adding the column idEtapa from table Etapa on the above query with no success. Anyway, I don't like to use this kind of clauses to get rid of the problem beacause it may cause another. So I would like to know if any of you have any idea on how just returning one record from etapa not regarding whether are they are related to several partida's record related to the same recurso's record?

Related

SQL query for Finding data with join or where within same table from multi tables

Im sorry i cant explain the question
I have a problem that i need to join 4 tables together to find some information. Im using inner join which is bringing me the right data but duplicate row having a minor change data. Lets say im getting this data
See the Table here
If we look at the results. At the last 4 rows we can notice simillar results. What i want to achieve is these 4 rows converted into 2.
I only want rows whose account id = vehicle account id and 110. I want these two rows. The join query i write is as follows
select Distinct vh.VehicleNo,jd.AccountID, tr.ID,jd.Memo,je.Description, jd.Cr,jd.Dr ,jd.Detail, je.JEntryId, je.ExpenseID from tbl_JDetail jd
inner join tbl_JEntry je on je.JEntryId = jd.JEntryID
inner join tbl_Trip tr on tr.ID = je.RefID
inner join tbl_Vehciles vh on vh.VID = tr.VehicleID
I really need to achieve this.. Any help would be appreciated how can i achieve. What i want is let me write the query in simple langauge
The query should first find rows in jdetail with accountid = 110. Then get its jentryid . Then in Jentry it should find the tripid and in trip table i have the vehicle id. Vehicle table contains vehicle id.
Then the query should find in jdetail with same jentryid and vehicleaccountid
i need jdetail accountid = 110 and accountid = vehicle.accountid
The vehicle relation is Jdetail > Jentry > Trip > Vehicle
i hope i was clear enough
Please add supporting information (create table statements, sample data, current output and desired output) to your question. As you have not included supporting information, I am unable to test this. This is my "best guess" based on your description.
select Distinct vh.VehicleNo,jd.AccountID, tr.ID,jd.Memo,je.Description, jd.Cr,jd.Dr ,jd.Detail, je.JEntryId, je.ExpenseID
from tbl_JDetail jd
inner join tbl_JEntry je
on je.JEntryId = jd.JEntryID
inner join tbl_Trip tr
on tr.ID = je.RefID
inner join tbl_Vehciles vh
on vh.VID = tr.VehicleID
and vh.AccountID = jd.AccountID
where jd.AccountID = 110
Solved it by using 2 CTEs. CTE1 finds the jentry_id of all records using account ID = 110
and CTE2 find all the required data with inner join cte on cte.JEntryId = jd.JEntryID
It solved all my problems..
Thankyou. Hope it help someone else too

SQL LEFT JOIN with possible join condition duplicate match

Here is my query so far:
SELECT
b.cs_bidding_id, b.cs_bidding_user_id,
floor(AVG(u.cs_rating)) AS cs_user_rating
FROM cs_biddings b LEFT JOIN
cs_user_ratings u ON u.cs_user_rated_id = b.cs_bidding_user_id
I would like to get the avg rating of the user's per bidding post.
However this does not work for multiple biddings because whenever the join condition is satisfied, it wont let me fetch other avg rating for other biddings that shares the same bidding_user_id
desired result:
Unsummarized Query:
SELECT
b.cs_bidding_id,
b.cs_bidding_title,
b.cs_bidding_details,
b.cs_bidding_user_id,
b.cs_bidding_permalink,
b.cs_bidding_added,
b.cs_bidding_picture,
b.cs_bidding_status,
b.cs_bidding_location,
floor(AVG(u.cs_rating)) AS cs_owner_rating
FROM cs_biddings b LEFT JOIN
cs_user_ratings u ON u.cs_user_rated_id = b.cs_bidding_user_id
Your query is malformed. It is an aggregation query (because of the AVG()) but the SELECT columns are inconsistent with the aggregation columns (well, there are none of those).
Fixing the group by might fix your problem:
SELECT b.cs_bidding_id, b.cs_bidding_user_id,
floor(AVG(u.cs_rating)) AS cs_user_rating
FROM cs_biddings b LEFT JOIN
cs_user_ratings u
ON u.cs_user_rated_id = b.cs_bidding_user_id
GROUP BY b.cs_bidding_id, b.cs_bidding_user_id;
I'm not sure if you want both columns in the GROUP BY (and the result set). However, without sample data and desired results, it is unclear what you actually intend.

SQL query for large amount of data with many joins

I have written a sql query for my requirement.
This is working fine for me. This is taking 0.0006 sec to execute.
I want to know from sql experts "will this work fine with large amount of data?".
I have written my query below.
SELECT HM_customers.id,
HM_customers.username,
HM_customers.firstname,
HM_customers.lastname,
HM_customers.company,
HM_customers_address_bank.field_data
FROM HM_orders
JOIN HM_order_items
ON HM_order_items.order_id = HM_orders.id
JOIN HM_bid
ON HM_order_items.bid_id = HM_bid.bid_id
JOIN HM_customers
ON HM_bid.user_id = HM_customers.id
JOIN HM_customers_address_bank
ON HM_customers_address_bank.id = HM_customers.default_billing_address
WHERE HM_orders.id = '4'
Any expert can advice me or let me know how can I improve this query. Please suggest me if any issue in this query.
NOTE:- This is a simple query. But I want to know, will this work with large amount of data with less time
You don't need to include the orders table:
SELECT c.id,
c.username,
c.firstname,
c.lastname,
c.company,
cb.field_data
FROM HM_order_items oi
JOIN HM_bid b
ON oi.bid_id = b.bid_id
JOIN HM_customers c
ON b.user_id = c.id
JOIN HM_customers_address_bank cb
ON cb.id = c.default_billing_address
WHERE oi.order_id = '4';
Your query can also result in duplicate rows, if a customer bids on the same items multiple times. If you put in a select distinct, then you will incur overhead of duplicate elimination. If this becomes a problem, you will probably want to restructure the query as an exists.
There are few points worth noting
1) The reference to an outer table column in the WHERE clause prevents the OUTER JOIN from returning any non-matched rows, which implicitly converts the query to an INNER JOIN. This is probably a bug in the query or a misunderstanding of how OUTER JOIN works.
2) Selecting all columns with the * wildcard will cause the query's meaning and behavior to change if the table's schema changes, and might cause the query to retrieve too much data. You should only choose columns you need.
Please make your driven table to 'HM_customers' as all your data is coming from this table and change your join like this way, hopefully this will help you :)
SELECT hmCust.id,
hmCust.username,
hmCust.firstname,
hmCust.lastname,
hmCust.company,
hmCustAdd.field_data
FROM HM_customers hmCust
INNER JOIN HM_bid hmBid
ON hmBid.user_id = hmCust.id
INNER JOIN HM_customers_address_bank hmCustAdd
ON hmCustAdd.id = hmCust.default_billing_address
INNER JOIN HM_order_items hmOrderItem
ON hmOrderItem.order_id = hmBid.bid_id
INNER JOIN HM_orders hmOrder
ON hmOrder.id = hmOrderItem.order_id
WHERE hmOrder.id = '4'

Inefficient Query

SELECT submissions.created_at, guests.accepted
FROM submission
INNER JOIN guests
ON guests.event_id = 1
ORDER BY submissions.created_at ASC;
Currently this query is taking a long time to run (may not even return everything).
What I am trying to accomplish:
Grab the field submissions.created at and guests.accepted (the two are linked by a submission_id)
given a certain event_id (event 1 for example).
What is wrong with my query?
You forgot to give the JOIN condition in your query. Try this:
SELECT submissions.created_at, guests.accepted
FROM submission s
INNER JOIN guests g on g.event_id = s.submissions_id
where guests.event_id = 1
ORDER BY submissions.created_at ASC;
SELECT submissions.created_at, guests.accepted
FROM submission
INNER JOIN guests
ON guests.(column to match against) = submissions.(column to match on)
where guests.event_id=1
ORDER BY submissions.created_at ASC;
As many others here have already said, your join is a little goofed. It's attempting to join the one row that matches in the guests table against every single row in the submission column.
You would need to do your join like this :
Inner join guest on guest.event_id = submissions_id
where guest.event_id = 1
When you join you need to join on two columns from different table (most of the time id columns)
You can read the MySQL example for more explanation. And here is the link to the MySQL reference manual

SQL query to join columns in result

I'm a complete SQL noob and have no idea how to utilize JOINs. If someone could help with this query, it would be great.
I have a table questions which contains two columns: queid and que.
Another table options, contains the corresponding options for the questions, and has columns optionid, queid,option.
How can I do a SELECT statement such that I can join both tables together based on queid ?
Something like:
SELECT * from questions,options where queid=1
You should try this:
SELECT que.*, opt.* FROM questions que
INNER JOIN options opt ON que.queid = opt.queid
WHERE que.queid = 1
INNER JOIN loads questions and options having at least one corresponing record in every table.
If you need to get all questions (even the ones not having options) you could use
SELECT que.*, opt.* FROM questions que
LEFT JOIN options opt ON que.queid = opt.queid
WHERE que.queid = 1
LEFT JOIN always loads questions and, if they have options, their options too; if not you get NULL for options columns.
May be by
SELECT * FROM questions q JOIN options o ON q.queid=o.queid WHERE q.queid=1
SELECT q.*,o.* FROM questions q
JOIN options o ON q.queid = o.queid
WHERE q.queid = 1
SELECT *
FROM questions
JOIN options ON questions.queid = options.queid
WHERE questions.queid = 1
You can join two related tables using the column that they have in common.
in your case you can write :
SELECT * FROM Questions as Q INNER JOIN Options O ON Q.queid=O.queid WHERE Q.quid=1
You can also omit the where part like this :
SELECT * FROM Questions as Q INNER JOIN Options O ON Q.queid=O.queid AND Q.quid=1
There are different kind of joins :
INNER
OUTER(Left,Right,Full)
By inner join you mean that only records that are common in both tables are returned
When you use outer join all the records on the given side are return plus the records that have corresponding values on the other side otherwise instead of the other side values you will get null.