A Query inside a Query.. Long loading time - php

Heyy i think i need to do a query inside a query.
Here is what i tried to do(it seems to work but it takes forever to load) :
$query="SELECT * FROM Table1";
$results=mysql_query($query);
while($row=mysql_fetch_array($results)){
$bnr=$row['COL 1'];
$usg=$row['COL 19'];
echo"$bnr hat $usg <br /> ";
$sqlupdate="UPDATE TABLE_1
SET
Usg='$usg'
WHERE
bnr = '$bnr'";
mysql_query($sqlupdate);
}

Yes, updating many rows individually will take a long time regardless of whether you're doing it inside another query.
But certainly running two queries on the same database, at the same time will not help the situation at all!
That said, the good news is that in your example you're able to perform the update entirely on the server using an update with a join.
UPDATE TABLE_1 as TDest
INNER JOIN TABLE1 as TSrc
ON TDest.bnr = TSrc.`COL 1`
SET TDest.Usg = TSrc.`COL 19`

I think the MySQL query that you want is:
update tdest t1 join
tdest t2
on t1.bnr = t2.`Col 1`
set t1.usg = t2.`Col 19`;

Related

How to optimize long query that displays thousands of data

I have almost thousands of data to display for my reports and it makes my browser lags due to the heavy data. I think that my query is the real problem. How can I optimized my query? is there something that I should add in my query?
I am using Xampp which supports PHP7.
SELECT
`payroll_billed_units`.`allotment_code`,
`payroll_billed_units`.`category_name`,
`payroll_billed_units`.`ntp_number`,
`payroll_billed_units`.`activity`,
`payroll_billed_units`.`regular_labor`,
`payroll_sub`.`block_number`,
(SELECT
GROUP_CONCAT(DISTINCT `lot_number` SEPARATOR ', ')
FROM
`payroll_billed_units` `lot_numbers`
WHERE
`lot_numbers`.`allotment_code` = `payroll_billed_units`.`allotment_code`
AND `lot_numbers`.`category_name` = `payroll_billed_units`.`category_name`
AND `lot_numbers`.`ntp_number` = `payroll_billed_units`.`ntp_number`
AND `lot_numbers`.`activity` = `payroll_billed_units`.`activity`) AS `lot_numbers`,
(SELECT
COUNT(`billed`.`ntp_id`)
FROM
`regular_ntp` `billed`
WHERE
`billed`.`allotment_code` = `payroll_billed_units`.`allotment_code`
AND `billed`.`category_name` = `payroll_billed_units`.`category_name`
AND `billed`.`ntp_number` = `payroll_billed_units`.`ntp_number`
AND `billed`.`activity` = `payroll_billed_units`.`activity`) AS `billed`,
(SELECT
COUNT(`approved`.`id`)
FROM
`payroll_billed_units` `approved`
WHERE
`approved`.`allotment_code` = `payroll_billed_units`.`allotment_code`
AND `approved`.`category_name` = `payroll_billed_units`.`category_name`
AND `approved`.`ntp_number` = `payroll_billed_units`.`ntp_number`
AND `approved`.`activity` = `payroll_billed_units`.`activity`) AS `approved`
FROM
`payroll_billed_units`
JOIN payroll_transaction ON payroll_billed_units.billing_number =
payroll_transaction.billing_number
JOIN payroll_sub ON payroll_transaction.billing_number =
payroll_sub.billing_number
WHERE payroll_billed_units.billing_date = '2019-02-13'
AND payroll_transaction.contractor_name = 'Roy Codal' GROUP BY allotment_code, category_name, activity
I was expecting that it will load or display all my data.
The biggest problem are the dependendt sub-selects, they are responsible for a bad performance. A sub-select will be executed for EVERY ROW of the outer query. And if you cascade subs-selects, you'll quickly have a query run forever.
If any of the parts would yield only 5 resultsets, 3 sub-select would mean that the database has to run 625 queries (5^4)!
Use JOINs.
Several of your tables need this 'composite' index:
INDEX(allotment_code, category_name, ntp_number, activity) -- in any order
payroll_transaction needs INDEX(contractor_name), though it may not get used.
payroll_billed_units needs INDEX(billing_date), though it may not get used.
For further discussion, please provide SHOW CREATE TABLE for each table and EXPLAIN SELECT ...
Use simply COUNT(*) instead of COUNT(foo). The latter checks the column for being not-NULL before including it. This is usually not needed. The reader is confused by thinking that there might be NULLs.
Your GROUP BY is improper because it is missing ntp_number. Read about the sql_mode of ONLY_FULL_GROUP_BY. I bring this up because you can almost get rid of some of those subqueries.
Another issue... Because of the "inflate-deflate" nature of JOIN with GROUP BY, the numbers may be inflated. I recommend you manually check the values of the COUNTs.

update a column with a value coming from an inner join

i need to update a lot of db values, so i guess it's better to use a sql statement, maybe creating and uploading a php file and running it from time to time.
in my db i have 3 related tables, let's say
tableA_label
tableB_image
tableC_text
the relations are as follows:
tableaA_label.ImageID refers to tableB_image.ID
tableB_image.TextID refers to tableC_text.ID
my goal is:
update tableA_label.Name
tableA_label.Name = tableC_text.title
where
tableC_text.ID = tableB_image.TextID
and
tableB_image.ID = tableA_label.ImageID
.....
how can accomplish this using an sql statement?
thank you for supporting
Try this query:
UPDATE tableA_label SET
tableA_label.Name = (SELECT TableC_text.title FROM TableC_text INNER
JOIN TableB_image ON TableB_image.TextID = TableC_text.ID
WHERE TableB_image.ID = tableA_label.imageID)

How to execute 2 more query in php

I have two queries that will be executed simultaneously. What should I do?
Thanks for any help :-).
Here is my code:
$sql1 = mysql_query("SELECT tregmk.kmk,tmmatakuliah.nmk,ifnull(tmmatakuliah.sks,0) AS sks FROM tregmk JOIN tmmatakuliah
ON (tregmk.kmk=tmmatakuliah.kmk) LEFT JOIN v_all_nilai_kk ON ((tregmk.kmk=v_all_nilai_kk.kmk) AND
(v_all_nilai_kk.stambuk=$_SESSION[stambuk]) AND (v_all_nilai_kk.nilai > 2)) WHERE (tregmk.tahunajarn=$thajaran)
and (tregmk.semester=$smster) AND (tregmk.fakultas=$fakpilihan) AND (tregmk.prodi=$prodi) AND (tregmk.jenjang=$jenjang) AND
(v_all_nilai_kk.kmk is null) AND (tmmatakuliah.nokur=$no_kur)");
$sql2 = mysql_query("SELECT trkrs.nid,trkrs.iplalu,trkrs.sksdicapai,trkrs.sksrencana,trkrs.sksdiambil,
trkrs.ipk,trkrs.konsentrasi,trkrs.tanggal,tdkrs.kmk,tdkrs.statskmk,tdkrs.tanggal,tmdos.nid,tmdos.nama,
tmmhs.nasert FROM trkrs JOIN tdkrs ON (trkrs.idkrs=tdkrs.idkrs),tmmhs,tmdos where
(tmmhs.stambuk=right(trkrs.idkrs,10)) AND (tmdos.nid=trkrs.nid) AND (trkrs.idkrs=$idkrs)");
Why do you need to run them at the same time? It doesn't look like either well affect the result of the other, so why can't you just run them one after the other then use the results?
If you MUST run them at the same time, you'll have to combine them into a single query and use the results from that - but practically that would be no different to running them right after each other anyway.
If there reason is based on time, you could just pull the time when each query is run and use that?

update table using variable sprintf using Join

Im trying to set a variable using sprintf via a Join Query, then update each time this appears in the table using the ID loaded into the query.
The update works fine if I use a slightly different query but one that gives an identical set of results, so have come to the conclusion Im doing something silly.
Here is a selection below:
//below is a simpler version of what I would like to work with the update
$sql=sprintf("SELECT `test`.`id` FROM `test` JOIN `test2` ON (test.agent=test2.user) WHERE `test`.`type`='new' AND `test2`.`note` = 'p';
//this is what works, even though the output (list of test.id) is identical to above
$sql=sprintf("SELECT `id` FROM `test` WHERE `test`.`type`='new' AND `agent`='test.user';
//here is my update that works with the second select
if($ref_id = mysql_one_data($sql)){
$updateSQL= sprintf("UPDATE `test` SET `type`='testdata', `priority`=%s, `note`=%s WHERE `id`=%s;",SQLVal('100', "int"),SQLVal($note, "text"),SQLVal($ref_id, "int"));
$result = mysql_query($updateSQL) or die(mysql_error());
$processed=TRUE; $result="updated";
$count_converted++;
}
Any ideas? I'm at a total loss! As I said both queries give 100% the same output, so the variable produced should be the same right? and so if one update works when it finds a corresponding value the other should too.

Retrieving a table alias

I have several queries that have a same filter.
For example:
Filter:
$criteria = "AND id_student = 1 AND id_major = 2 ";
Query 1:
$query1 = "SELECT * FROM student AS t0
LEFT JOIN major AS t1 ON t0.id_major = t1.id
WHERE 1=1 ";
Query 2:
$query2 = "SELECT * FROM lecturer AS t0
LEFT JOIN major AS t1 ON t0.id_major = t1.id
LEFT JOIN student AS t2 ON t2.id_major = t1.id
WHERE 1=1 "
It will be run as
$query1.$criteria
and
$query2.$criteria
As you can see, this will yield a query error, since id_major is ambiguous.
My problem is, that this query is very big in number, so I prefer not to hard-code and change the $criteria and $query individually.
I've tried to change the $criteria into
$criteria = "AND student.id_student = 1 AND major.id_major = 2 ";
But it does no better, it gave me errors of "did you mean t0", "did you mean t2", etc.
So, can I do something like, get an alias of a table? So I can put it in the $criteria
$criteria = "AND (get-alias-code).id_student = 1 AND (get-alias-code).id_major = 2 ";
Or any other method?
I am not the primary developer of this program, just a bug-fixer so I cannot change much of this program (because those queries may affect another page).
Use the aliases you have for your tables already, and set the criteria to be
$criteria = "AND t0.`id_student`='1' AND t1.`id_major`='2' ";
I strongly recommend using backtics and ticks as well, it helps avoiding funny mistakes with table or field names like 'order' :)
Then all you need to ensure is that the table that needs the criteria applied gets the correct alias every time
Edit:
Hm...alternatively, you can remove aliasing from all queries.
I honestly don't think that there's any mysql feature to get the aliases for tables. You could run a string analyser code snippet to find them (knowing all table names it may not even be hard to do) but that looks like a very ugly solution IMHO.
I don't know away to handle it on sql but you can handle it with on array for example
$alias[1]["student"] = "t0"; // it means on query 1 your alias for student is t0
now you can use this variable on your filter
$criteria = "AND ".$alias[1]["student"].".id_student = 1 AND ".$alias[1]["major"].".id_major = 2 ";
I think it's one of fast ways to change your filter without changing all of queries.
hope It helps
Wrap the whole thing in an outer query like this:
"SELECT * FROM (".$query1.") a ".$criteria;
Assuming of course that the original query didn't create multiple columns with the same name, you can now reference them without the alias.

Categories