Combine 2 MySQL queries into 1 query - mysql

I'm trying to combine these two queries into a single query but I'm not having much luck and I'm starting to think that it's not possible.
The value returned in transfer_dtl from the first query is passed into the second query FROM. This value is an actual table name that is stored in the first query. This is currently done with php and loops through, but I wanted to eliminate that step if possible.
SELECT id, client, loc, transfer_dtl, update_processed FROM tbl_master WHERE downtime_update='Y'
transfer_dtl
-------------
load_dtl_1
load_dtl_5
load_dtl_7
load_dtl_9
SELECT added_datetime FROM $transfer_dtl WHERE client='1' AND loc='2' AND scale='3' AND type='D' ORDER BY added_datetime DESC LIMIT 1
pseudo code...
if($added_datetime > $update_processed)
then add to a list of scales to update
Basically by combining these two queries together what I need is a distinct list of any scale that is marked to update.

Related

Calculate sum from MySQL server or from application

I have a MySQL table which has two columns : ID and count. It has an index on ID field.
Now if i have to get sum of all the count between two IDs, I can write a query like:
Select SUM(count) from table where id between x and y
or i can get
select count from table where id between x and y
And then loop through the result and calculate the sum of the count on my application code
Which one is better, considering the speed is the essential thing here. Will indexing on the count help?? Or can i write a different SQL?
Would indexing on the count column help in any way?
I have around 10000 requests per second coming in and I am using a load balancer and 5 servers for this.
The second one is the correct one. There's no need to sum a count, as the count comes back as a single value. It only needs to be run once.
Unless you have a column named count, in which you want to sum all the values...
EDIT
Because you are saying you have a column named Count, you would use the first query:
Select SUM(count) from table where id between x and y
Use approach 1 as you would save on fetching data from MySQL and iterating over it.
The time taken by MySQL to execute either of your queries would be nearly the same but the second approach would require looping through the results and summing them; unnecessary overhead.

UNION of (2) SELECT with WHERE, GROUP BY and ORDER BY from (1) table

I want to combine two queries with different WHERE clauses and overlapping results. How can I use UNION to combine the result to be distinct by case_id?
First query
SELECT
O.case_id,
O.otc_eff_date,
DATE_FORMAT(STR_TO_DATE(O.otc_eff_date, '%Y%j'),'%m/%d/%Y') otc_ef_date,
O.otc_type,
O.case_rsf,
O.otc_rsn,
O.otc_rlse_to,
O.seg_ent_date,
O.Seg_chg_date,
O.otc_case_status,
O.otc_opn_seq_cnt,
O.filler
FROM NU.RawCaseOTC O
WHERE O.otc_eff_date BETWEEN 2011182 AND 2012182
GROUP BY O.case_id
ORDER BY otc_ef_date
Second query
SELECT
MAX(otc_eff_date) MAX_OTC_EFF_DATE,
case_id,
otc_eff_date,
otc_type,
case_rsf,
otc_rsn,
otc_rlse_to,
seg_ent_date,
Seg_chg_date,
otc_case_status,
otc_opn_seq_cnt,
filler
FROM NU.RawCaseOTC
WHERE (otc_case_status != 'C') AND (otc_eff_date <='2011182')
GROUP BY case_id
ORDER BY otc_eff_date
If you UNION this 2 selects and then make another select over it, you can make case_id distinct if you put each other columns in MAX or MIN or SUM or COUNT or AVG ...
If you want first row to be distinct, second row must be in aggregate function.
Be careful! Yes, you can do things like wrap the two queries in a nested SELECT with a GROUP BY on the outer query... but it will absolutely kill your performance, because the DB will need to save the whole of the output of the inner queries to a temp table and requery them. If you've got even a moderate number of records being queried, it's just not going to be pretty.
You'd be much better off trying to combine the two queries into a single query in the first place.
When you're looking at queries like this it can get complex to do it, but it can be done, and the performance ought to be significantly better.
I don't have time to come up with the perfect query for you right now, but there have been a few other questions here and elsewhere about how to do this sort of thing. Maybe one of these will help you?
Combining two GROUP BY queries grouped by the same column
Combine two small queries (that group by different values) into one query
http://forums.devshed.com/mysql-help-4/combining-results-of-two-group-by-queries-806682.html

Saving time in queries on sql

I have a scenario. I have say 300 records in my table. I execute a query to get the total count. Then , since i have to implement pagination,
I select the data from the same table using limits according t the count. I was thinking if i can get the count and data in a single query.? .
I tried below code:
Select * ,count(*) as cnt from table;
But this gave me the total count but only 1 record!
Is there a way to save my time exhausted in query and get results in a single query?
something like:
select t1.*,t2.cnt
from table t1
cross join (select count(*) as cnt from table) t2
limit 'your limit for the first page'
or
select *,(select count(*) from table) as cnt
from table
limit 'your limit for the first page'
You can get information in data structure you mentioned, but there is really no reason to do it. There is no performance problem when you do two queries - one for getting rows count and another for data selection. You don't save anything when you try to select all information in one query. Do two simple queries instead, it will be better solution for your app - you will preserve its simplicity and clarity.
Using two queries might not be as bad as you may think, you can read this for more information.

Best way to combine multiple advanced mysql select queries

I have multiple select statements from different tables on the same database. I was using multiple, separate queries then loading to my array and sorting (again, after ordering in query).
I would like to combine into one statement to speed up results and make it easier to "load more" (see bottom).
Each query uses SELECT, LEFT JOIN, WHERE and ORDER BY commands which are not the same for each table.
I may not need order by in each statement, but I want the end result, ultimately, to be ordered by a field representing a time (not necessarily the same field name across all tables).
I would want to limit total query results to a number, in my case 100.
I then use a loop through results and for each row I test if OBJECTNAME_ID (ie; comment_id, event_id, upload_id) isset then LOAD_WHATEVER_OBJECT which takes the row and pushes data into an array.
I won't have to sort the array afterwards because it was loaded in order via mysql.
Later in the app, I will "load more" by skipping the first 100, 200 or whatever page*100 is and limit by 100 again with the same query.
The end result from the database would pref look like "this":
RESULT - selected fields from a table - field to sort on is greatest
RESULT - selected fields from a possibly different table - field to sort on is next greatest
RESULT - selected fields from a possibly different table table - field to sort on is third greatest
etc, etc
I see a lot of simpler combined statements, but nothing quite like this.
Any help would be GREATLY appreciated.
easiest way might be a UNION here ( http://dev.mysql.com/doc/refman/5.0/en/union.html ):
(SELECT a,b,c FROM t1)
UNION
(SELECT d AS a, e AS b, f AS c FROM t2)
ORDER BY a DESC

optimizing a complex query in mysql

I have two questions here but i am asking them at once as i think they are inter-related.
I am working with a complex query (Multiple joins + sub queries) and the table is pretty huge as well (around 2,00,000 records in this table).
A part of this query (a LEFT JOIN) is required to find a record which has a second lowest value in a cetain column among all the records associated with the primary key of the first table. For now I have isolated this part and thinking on the lines of -
SELECT id FROM tbl ORDER BY `myvalue` ASC LIMIT 1,1;
But there is a case where, if there is only 1 record in the table, it must return that record instead of NULL. So my first question is how do write a query for this ?
Secondly, considering the size of the table and the time its already taking to run even after creating indexes, I understand that adding any more complexity to it in order to achieve the above part might affect the querying time dramatically.
I cannot decompose joins because I need to get some of the columns for the ORDER BY clause (the application has an option to sort the result by these columns, the above column "myvalue" being one of them)
What would be the way(s) to approach this problem ?
Thanks
Something like this might work
COALESCE(
(SELECT id FROM tbl ORDER BY `myvalue` ASC LIMIT 1,1),
(SELECT id FROM tbl ORDER BY `myvalue` ASC LIMIT 0,1))
It selects the first non null value from the list provided.
As for the complexity of the query, post the whole thing so we can take a look at it.