SQL Query displaying duplicate results suddenly - mysql

I am stumped after a day of troubleshooting. This MySQL query has been running successfully for a month and all of the sudden I am receiving duplicate results which is fouling up the entire management program it is relevant to.
My troubleshooting included searching the database for duplicate entries and none existed. For example, I used the search command in phpMyAdmin to display the entries where entry_id = 45 and field_id = 65. The result of the search displayed only one result which is correct. As of yesterday the below query displays the same result twice.
Query:
SELECT f.id, f.title, f.type, f.name, v.id AS f_id, v.field_value
FROM jos_directory_enf AS v
LEFT JOIN jos_directory_field AS f ON f.id = v.field_id
WHERE v.entry_id = 45 AND v.field_id = 65

You may want to see if your joining tables have any duplicates in them that will result in more results to your main query.

It is difficult to answer your question without knowing details about your schema and the duplicated result. I guess your data was updated since the time where no duplicated were presented.
Look if v.id and v.field_value contain NULL values more than once for the same v.field_id or there rows with the same values for the columns, which you project in one of the two tables. Look if f.id or v.field_id have the same values in different rows.

Related

Very slow Left Join on small/medium tables

I have an issue with a particular left join slowing down an important query drastically. Using PHPMyAdmin to test the query, it states that the query took 3.9 seconds to return 546 rows, though I had to wait 67 seconds to see the results which struck me as odd.
There are two tables involved:
nsi (1,553 rows) and files (233,561 rows). All columns mentioned in this query are indexed individually as well as there being a compound index on filejobid, category and isactive in the files table. Everything being compared is an integer as well.
The goal of this watered down version of the query is to display the row from the nsi table once and be able to determine if someone has uploaded a file in category 20 or not. There can be multiple files but should only be one row, hence the grouping.
The query:
SELECT
nsi.id AS id,
f.id AS filein
FROM nsi nsi
LEFT JOIN files f
ON f.filejobid=nsi.leadid AND f.category=20 AND f.isactive=1
WHERE nsi.isactive=1
GROUP BY nsi.id
The 67 second load time for this data is simply unacceptable for my application and I'm at a loss as to how to optimize it any further. I've indexed and compound indexed. Should I just be looking into a new more roundabout solution instead?
Thank you for any help!
This is your query, which I find a bit suspicious, because you have an aggregation but not aggregation function on f.id. It will return an arbitrary matching id:
SELECT nsi.id AS id, f.id AS filein
FROM nsi LEFT JOIN
files f
ON f.filejobid = nsi.leadid AND f.category = 20 AND f.isactive = 1
WHERE nsi.isactive = 1
GROUP BY nsi.id;
For this query, I think the best indexes are files(filejobid), category, isactive) and nsi(isactive, filejobid, id).
However you can easily rewrite the query to be more efficient, because it doesn't need the group by (assuming nsi.id is unique):
SELECT nsi.id AS id,
(SELECT f.id
FROM files f
WHERE f.filejobid = nsi.leadid AND f.category = 20 AND f.isactive = 1
LIMIT 1
) AS filein
FROM nsi
WHERE nsi.isactive = 1;
The same indexes would work for this.
If you want a list of matching files, rather than just one, then use group_concat() in either query.

LEFT JOIN tables mysql, not getting the data correctly

I don't know if this is a problem with my query, or if I am using the wrong thing altogether.
Basically I have 2 tables, submission_data and codes. The codes can be managed in the system, and numbers are submitted against each code in the submissions page. However, if a new code is added after some submissions have been added, the query I use to grab all of the data for a specific submission does not show any new codes added as it is not present in the submission_data table.
SQLFIDDLE
My query is as follows:
SELECT c.code, sd.code_value from submission_data sd
LEFT JOIN codes c ON c.ID = sd.code_id
WHERE submission_id = 1
I should be seeing the S code in the results, obvsiously with a value of 0 as there are no entries.
Have I done the query the wrong way around (selecting from the wrong table first), or is it something to do with my JOINS? I have tried different combinations and keep getting the same results
This query should work:
SELECT c.code, sd.code_value
FROM codes c
LEFT JOIN submission_data sd ON c.ID = sd.code_id AND submission_id = 1
It gets all the rows from codes. For each row from codes it finds all the matches (by code.ID) from submission_data that also have submission_id = 1. If no such row is found in submission_data, it returns NULL for sd.code_value.

Invalid results returning from a multi-table SELECT Statement

I have a Database with the following structure:
http://i.imgur.com/DFZz3Py.png
I'm trying to run a select statement, getting information from multiple tables, however it keeps bringing me duplicate results. The statement I'm using is:
SELECT StockReceipts.StockID, StockReceipts.Quantity, StockPriceHistory.Price
FROM StockReceipts,StockPriceHistory,Receipts
WHERE (Receipts.ReceiptID = 1) AND (Receipts.OrderDate BETWEEN StockPriceHistory.DateStart AND StockPriceHistory.DateEnd)
And the results i'm getting are:
http://i.imgur.com/2ZrgYyZ.png
What I actually want is matching rows from the stockreceipts table,
but with the price for each item of stock (the price that was within the date & time of ordering - OrderDate taken from the Receipts table) as well, taken from the StockPriceHistory table. I don't understand why it's making up duplicate/incorrect rows when there are only two rows in the StockReceipts table for that receipt.
Can anyone help? Thanks
SELECT
SR.StockID,
SR.Quantity,
SPH.Price
FROM
Receipts R
JOIN StockReceipts SR
on R.ReceiptID = SR.ReceiptID
JOIN StockPriceHistory SPH
on SR.StockID = SPH.StockID
WHERE
R.ReceiptID = 1
AND R.OrderDate BETWEEN SPH.DateStart AND SPH.DateEnd
You had no JOIN conditions between the tables leaving it a Cartesian result... For every record in one, grabbed entries from all other table rows.

MySQL grouping error

I'm trying to run a query on a table to see how many unique users have a usage record in the system at a given point. I've been working with the following query, but I've yet to see a proper result.
SELECT count(distinct usageUser), divisionName
FROM records R
INNER JOIN locate L
ON L.computerID=R.usageComputerID
WHERE R.usageWhen LIKE "2012-07-08T12:%"
GROUP BY L.divisionName;
Currently the query returns 18, for each division in the joined table. Without the GROUP BY clause I get the same number of records.
EDIT:
I ran the query again, with suggestions from a comment. By removing the group by and count clause, I get this this (too big to post). This data is very poorly formatted, unfortunately it's inherited and fairly large.
It is not possible for these users to have used every lab like it's listed.
SELECT count(*) cnt, L.divisionName, R.usageUser
FROM records R
INNER JOIN locate L
ON L.computerID=R.usageComputerID
WHERE R.usageWhen LIKE "2012-07-08T12:%"
GROUP BY L.divisionName,R.usageUser;

SQL Sum Query Behaving Strangely?

I'm having an issue getting this SQL query to work properly.
I have the following query
SELECT apps.*,
SUM(IF(adtracking.appId = apps.id AND adtracking.id = transactions.adTrackingId, transactions.payoutAmount, 0)) AS 'revenue',
SUM(IF(adtracking.appId = apps.id AND adtracking.type = 'impression', 1, 0)) AS 'impressions'
FROM apps, adtracking, transactions
WHERE apps.userId = '$userId'
GROUP BY apps.id
Everything is working, HOWEVER for the 'impressions' column I am generating in the query, I am getting a WAY larger number than there should be. For example, one matching app for this query should only have 72 for 'Impressions' yet it is coming up with a value of over 3,000 when there aren't even that many rows in the adtracking table. Why is this? What is wrong here?
Your problem is you have no join conditions, so you are getting every row of every table being joined in your query result - called a cartesian product.
To fix, change your FROM clause to this:
FROM apps a
LEFT JOIN adtracking ad ON ad.appId = a.id
LEFT JOIN transactions t ON t.adTrackingId = ad.id
You haven't provided the schema for your tables, so I guessed the names of the relevant columns - you may have to adjust them. Also, your transaction table may join to adtracking - it's impossible to know from your question, so agin you have have to alter things slightly. Hopefully you get the idea.
Edit:
Note: your group-by clause is incorrect. You either need to list every column of apps (not recommended), or change your select to only select the id column from apps (recommended). Change your select to this:
SELECT apps.id,
-- rest of query the same
Otherwise you'll get weird, incorrect, results.