MySQL count giving different result everytime - mysql

I am using a MySQL query to calculate the number of records based an certain where conditions. But each time the website/database is used by multiple users from multiple systems. The count result varies dramatically.
I have tried to find a lot but could not figure the issue. I am attaching the screen-shots. Please help!
Here's the screenshot: https://drive.google.com/file/d/0B4kI3aImsSLmaGN3cXo1Rk1saDg/view?usp=sharing
Structure of table:
CREATE TABLE IF NOT EXISTS `rap_partmpuser` (
`par_tmp_track` int(11) NOT NULL,
`par_tmp_exam` int(11) NOT NULL,
`par_tmp_user` int(11) NOT NULL,
`par_tmp_status` varchar(100) NOT NULL,
`par_tmp_sdate` date NOT NULL,
`par_tmp_edate` date NOT NULL,
`par_tmp_adate` date NOT NULL,
`par_tmp_tdate` date NOT NULL,
`par_terdate` date NOT NULL,
`par_tmp_score` int(11) NOT NULL,
`par_tmp_tques` int(11) NOT NULL,
`par_tmp_uopt1` varchar(250) NOT NULL,
`par_tmp_uopt2` varchar(250) NOT NULL,
`par_tmp_uopt3` varchar(250) NOT NULL,
`par_tmp_uopt4` varchar(250) NOT NULL,
`par_tmp_uopt5` varchar(250) NOT NULL,
`par_tmp_uopt6` varchar(250) NOT NULL,
`par_tmp_uopt7` varchar(250) NOT NULL,
`par_tmp_uopt8` varchar(250) NOT NULL,
`par_tmp_uopt9` varchar(250) NOT NULL,
`par_tmp_uopt10` varchar(250) NOT NULL,
`par_tmp_uopt11` varchar(250) NOT NULL,
`par_tmp_uopt12` varchar(250) NOT NULL,
`par_tmp_uopt13` varchar(250) NOT NULL,
`par_tmp_uopt14` varchar(250) NOT NULL,
`par_tmp_uopt15` varchar(250) NOT NULL,
`par_tmp_filter` int(11) NOT NULL,
`par_tmp_sfilter` int(11) NOT NULL,
`par_tmp_cpyid` int(11) NOT NULL,
`par_tmp_usrid` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
And my query is
SELECT count(*)
FROM `rap_partmpuser`
where par_tmp_cpyid='10106' and par_tmp_track='458'
and par_tmp_usrid='771' and par_tmp_status='Active'
Sometimes it gives me the result 46, sometimes 26, sometimes 70. The correct result is 70. Why is it different sometimes?

I think the answer is simple. I'm not sure that this is the only mistake.
SELECT count(*) FROM rap_partmpuser where par_tmp_cpyid=10106 and
par_tmp_track=458 and par_tmp_usrid=771 and par_tmp_status='Active';
Don't use 'single quotes' to check integer values like par_tmp_cpyid='10106'.Try above query if you get correct answer comment below.

$reponse = $bdd->prepare('
SELECT count(*)
FROM rap_partmpuser
where par_tmp_cpyid=10106 and par_tmp_track=458
and par_tmp_usrid=771 and par_tmp_status=\'Active\'');
$reponse->execute();
$donnees = $reponse->fetch();
echo $donnees[0] ;

Related

i want to optimize mysql query

Please guys help me to optimize the below query
SELECT
`dti`.`CompanyId`,
`dti`.`Samiti`,
`dti`.`toll_date`,
`dti`.`MajorFee`,
`dti`.`MinorFee`,
`dti`.`SawalFee`,
SUM(dti.Tmwt) as Tmwt,
SUM(dti.Localminor) as Localminor,
SUM(dti.Swt) as Swt,
SUM(dti.Twt) as Twt,
SUM(((dti.Tmwt * dti.MajorFee) + (dti.Localminor * dti.MinorFee) + (dti.Swt * dti.SawalFee))) as total_wages,
SUM((dti.Twt * dti.govt_charges)) as govt_deduction,
SUM((((dti.Tmwt * dti.MajorFee) + (dti.Localminor * dti.MinorFee) + (dti.Swt * dti.SawalFee)) - (dti.Twt * dti.govt_charges))) as net_amount,
(SELECT (SUM(ld.amount) + SUM(ld.advance_deduction))
FROM psac_liability_deduction ld
WHERE ld.status = "Active" AND
ld.from_date >="2017-08-24" AND
ld.to_date <="2017-08-31" AND
ld.deducted_for = dti.CompanyId
) as group_liability_deduction,
(SELECT CONCAT(SUM(wi.GroupLiabilityDeduction), "|", SUM(wi.AdvanceWagesDeduction))
FROM psac_wagesitem wi
WHERE wi.status="Active" AND
wi.from_date >= "2017-08-24" AND
wi.to_date <= "2017-08-31" AND
wi.MainGroup=dti.Samiti AND
wi.FishermanId=dti.CompanyId
) as wages_deduction,
(SELECT CONCAT(SUM(cdp.product_liability), "|", SUM(cdp.wages_liability))
FROM psac_cash_deposited_payment cdp
WHERE cdp.status="Active" AND
cdp.deposit_date >= "2017-08-24" AND
cdp.deposit_date <= "2017-08-31" AND
cdp.maingroup_id=dti.Samiti AND
cdp.fisherman_id=dti.CompanyId
) as cash_deposited,
`fm`.`Name` as `fishername`,
`fm`.`Code` as `fishername_code`,
`fm`.`Bank`,
`fm`.`IfscCode`,
`fm`.`AccountNo`
FROM `psac_dailytollinfo` `dti`
LEFT JOIN `psac_fisherman` `fm` ON `fm`.`ID`=`dti`.`CompanyId`
WHERE
`dti`.`status` = 'Active' AND
`dti`.`toll_date` >= '2017-08-24' AND
`dti`.`toll_date` <= '2017-08-31'
GROUP BY `dti`.`toll_date`, `dti`.`CompanyId`
ORDER BY `dti`.`toll_date` ASC
please help me to optimize this query. If i remove sub queries it will works perfect but with subqueries it takes too much time.
below are table structures
psac_dailytollinfo table
CREATE TABLE `psac_dailytollinfo` (
`ID` int(11) NOT NULL,
`toll_date` date NOT NULL,
`Point` int(11) NOT NULL,
`group_type` int(11) NOT NULL,
`Samiti` int(11) NOT NULL,
`DailytollId` int(11) NOT NULL,
`CompanyId` int(11) NOT NULL,
`Name` varchar(250) NOT NULL,
`govt_charges` float(15,2) NOT NULL,
`MajorFee` float(15,2) NOT NULL,
`MinorFee` float(15,2) NOT NULL,
`SawalFee` float(15,2) NOT NULL,
`Cqty` varchar(150) NOT NULL,
`Cwt` varchar(150) NOT NULL,
`Rqty` varchar(150) NOT NULL,
`Rwt` varchar(150) NOT NULL,
`Mqty` varchar(150) NOT NULL,
`Mwt` varchar(150) NOT NULL,
`Kqty` varchar(150) NOT NULL,
`Kwt` varchar(150) NOT NULL,
`Aqty` varchar(150) NOT NULL,
`Awt` varchar(150) NOT NULL,
`Sqty` varchar(11) NOT NULL,
`Swt` varchar(11) NOT NULL,
`Lqty` varchar(150) NOT NULL,
`Lwt` varchar(150) NOT NULL,
`Localminor` varchar(150) NOT NULL,
`Tmqty` varchar(150) NOT NULL,
`Tmwt` varchar(150) NOT NULL,
`Tqty` varchar(150) NOT NULL,
`Twt` varchar(150) NOT NULL,
`added_by` int(11) NOT NULL,
`updated_by` int(11) NOT NULL,
`added_date` datetime NOT NULL,
`updated_date` datetime NOT NULL,
`action_microtime` varchar(20) NOT NULL,
`status` enum('Active','Inactive','Deleted') NOT NULL DEFAULT 'Active'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
psac_liability_deduction table
CREATE TABLE `psac_liability_deduction` (
`ID` bigint(20) NOT NULL,
`wages_id` int(11) NOT NULL,
`wages_item_id` int(11) NOT NULL,
`amount` float(15,2) NOT NULL,
`advance_deduction` float(11,2) NOT NULL,
`group_type_id` int(11) NOT NULL,
`maingroup_id` int(11) NOT NULL,
`deducted_by` int(11) NOT NULL,
`deducted_for` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
`status` enum('Active','Inactive','Deleted') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Active',
`added_by` int(11) NOT NULL,
`updated_by` int(11) NOT NULL,
`added_date` datetime NOT NULL,
`updated_date` datetime NOT NULL,
`action_microtime` varchar(50) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
psac_wagesitem table
CREATE TABLE `psac_wagesitem` (
`ID` int(11) NOT NULL,
`wages_for` enum('Fisherman','Group') NOT NULL DEFAULT 'Fisherman',
`wages_id` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
`group_type_id` int(11) NOT NULL,
`MainGroup` int(11) NOT NULL,
`FishermanId` int(11) NOT NULL,
`MajorFee` float(15,2) NOT NULL,
`MinorFee` float(15,2) NOT NULL,
`SawalFee` float(15,2) NOT NULL,
`major_wt` float(15,2) NOT NULL,
`minor_wt` float(15,2) NOT NULL,
`sawal_wt` float(15,2) NOT NULL,
`major_wage` float(15,2) NOT NULL,
`minor_wage` float(15,2) NOT NULL,
`sawal_wage` float(15,2) NOT NULL,
`TotalWage` float(15,2) NOT NULL,
`group_liability` float(15,2) NOT NULL,
`advance_wages` float(15,2) NOT NULL,
`GovDeduction` float(15,2) NOT NULL,
`GroupLiabilityDeduction` float(15,2) NOT NULL,
`AdvanceWagesDeduction` float(15,2) NOT NULL,
`final_wages` float(15,2) NOT NULL,
`added_by` int(11) NOT NULL,
`updated_by` int(11) NOT NULL,
`added_date` datetime NOT NULL,
`updated_date` datetime NOT NULL,
`action_microtime` varchar(20) NOT NULL,
`status` enum('Active','Inactive','Deleted') NOT NULL DEFAULT 'Active',
`editable` enum('Lock','Unlock') NOT NULL DEFAULT 'Unlock'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
psac_cash_deposited_payment table
CREATE TABLE `psac_cash_deposited_payment` (
`deposit_id` int(11) NOT NULL,
`deposited_by` enum('Fisherman','Group') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Fisherman',
`deposit_date` date NOT NULL,
`group_type_id` int(11) NOT NULL,
`maingroup_id` int(11) NOT NULL,
`fisherman_id` int(11) NOT NULL,
`product_liability` float(11,2) NOT NULL,
`wages_liability` float(11,2) NOT NULL,
`receipt_number` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`remark` text COLLATE utf8_unicode_ci NOT NULL,
`status` enum('Active','Inactive','Deleted') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Active',
`editable` enum('Lock','Unlock') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Unlock',
`added_by` int(11) NOT NULL,
`added_date` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
`updated_date` datetime NOT NULL,
`action_microtime` varchar(20) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
You understand that you are looking at a full 8 days? If you only wanted one week, change <= to <.
Switch all tables to InnoDB.
Have a PRIMARY KEY for every table -- either a 'natural' PK (composed of one or more columns that, together, uniquely define each row), or an AUTO_INCREMENT.
dti needs INDEX(status, toll_date)
Don't use (m,n) on FLOAT, it leads to an extra roundoff.
Don't use FLOAT for money, it leads to a roundoff.
FLOAT (with or without (m,n)) contains no more than 7 significant digits.
Consider DECIMAL(11,2) instead of float(11,2).
Be cautious about using latin1 in one table and utf8 in another -- if you need to JOIN on a VARCHAR; it must have the same charset and collation in order to use an index.
Where practical, make the ORDER BY identical to the GROUP BY.
These composite indexes that are likely to help performance:
dti: INDEX(status, toll_date)
ld: INDEX(status, deducted_for, from_date)
ld: INDEX(status, deducted_for, to_date)
wi: INDEX(status, MainGroup, FishermanId, from_date)
wi: INDEX(status, MainGroup, FishermanId, to_date)
cdp: INDEX(status, maingroup_id, fisherman_id, deposit_date)
(The date must be last; the other column(s) can be in any order.)
If you still have performance problems with the subqueries after you have added those indexes, let's see EXPLAIN SELECT ... so we can look again.
Don't splay an array across columns:
`Cqty` varchar(150) NOT NULL,
`Cwt` varchar(150) NOT NULL,
etc
Consider having qty and wt as two columns in another table.
Could there be two different values for MajorFee in a single day for a single company? That, and other things say that the GROUP BY is improperly formed.

fetch data from table

I have the following table in my database
CREATE TABLE `sms_pool` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ag_id` VARCHAR(20) NOT NULL,
`sms_to` VARCHAR(15) NOT NULL,
`template_name` VARCHAR(100) NOT NULL,
`contents` VARCHAR(500) NOT NULL,
`bulk_flag` VARCHAR(1) NOT NULL,
`file_name` VARCHAR(100) NULL DEFAULT NULL,
`send_flag` VARCHAR(1) NOT NULL,
`creation_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_by` VARCHAR(20) NOT NULL,
`modification_date` DATETIME NULL DEFAULT NULL,
`modified_by` VARCHAR(20) NULL DEFAULT NULL,
`processing_msg` VARCHAR(2000) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
);
I wish to write a procedure/function which takes 'id' as input.
If 'id' is present in the table then it should return the corresponding row,
if 'id' = NULL then it should return all of the rows from the database.
NOTE : if 'id' is not present in table then it should return all of the rows.
How should I do this? Any help is appreciated.
Thank you in advance. :D
You probably mean
select * from sms_pool
where :id = id OR :id is null;

How to get the last record value of a particular column?

Query:
select total_amount from sales_return;
Output:
total_amount
157.00
8.00
1.00
52.00
I'm trying to get the last value ie, 52.0. So I tried the below query.
select total_amount from sales_return order by total_amount desc limit 1;
which shows the first value 157.00 as output. What I did wrong?
query for creating sales_return table.
'sales_return', 'CREATE TABLE `sales_return` (
`sales_return_no` varchar(12) DEFAULT NULL,
`sales_return_date` date DEFAULT NULL,
`bill_type` varchar(20) DEFAULT NULL,
`bill_no` varchar(12) DEFAULT NULL,
`bill_date` date DEFAULT NULL,
`cust_name` varchar(60) DEFAULT NULL,
`doctor_name` varchar(100) DEFAULT NULL,
`payment_mode` varchar(20) DEFAULT NULL,
`card_no` varchar(25) DEFAULT NULL,
`card_holders_name` varchar(20) DEFAULT NULL,
`bank_name` varchar(20) DEFAULT NULL,
`card_expiry` varchar(20) DEFAULT NULL,
`item_code` varchar(30) DEFAULT NULL,
`item_name` varchar(100) DEFAULT NULL,
`mfr_name` varchar(50) DEFAULT NULL,
`formulation` varchar(45) DEFAULT NULL,
`batch_no` varchar(100) DEFAULT NULL,
`qty` int(11) DEFAULT NULL,
`unit_price` double(12,2) DEFAULT NULL,
`expiry_date` date DEFAULT NULL,
`mrp` double(12,2) DEFAULT NULL,
`unit_discount` double(3,1) DEFAULT NULL,
`unit_vat` double(3,1) DEFAULT NULL,
`sub_total` double(12,2) DEFAULT NULL,
`total_discount` double(12,2) DEFAULT NULL,
`total_vat` double(12,2) DEFAULT NULL,
`total_amount` double(12,2) DEFAULT NULL,
`paid_amount` double(12,2) DEFAULT NULL,
`balance_amount` double(12,2) DEFAULT NULL,
`total_items` int(11) DEFAULT NULL,
`total_qty` int(11) DEFAULT NULL,
`adj_id` int(11) unsigned DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
Mysql has no concept of 'first record' or 'last record' without some context in the form of an order by. Without that order by the first and last records are indeterminate / meaningless.
From your provided table schema it would seem that sales_return_date would be a suitable field for determining an 'order' to the records. Ie, the last record entered, is the one entered most recently. So we need to order by that field, and then limit out results to just one 1.
select total_amount
from sales_return
order by sales_return_date desc
limit 1
Query:
select `total_amount` from `sales_return` order by `bill_date` desc limit 1
The above query may give you the last total_amount value.
Try this : here adj_id is unsigned so no negative values and may be role like primary key , so try this
select total_amount
from sales_return
order by adj_id desc
limit 1

Mysql select * from a where doesnt exist in b

Im having problems with constructing a query which filters out posts from table a, that already existing in table b.
Table A:
`bok_id` int(6) NOT NULL AUTO_INCREMENT,
`tid` time NOT NULL,
`datum` date NOT NULL,
`datum_end` date NOT NULL,
`framtid` varchar(5) NOT NULL,
`h_adress` varchar(100) NOT NULL,
`l_adress` varchar(100) NOT NULL,
`kund` varchar(100) NOT NULL,
`typ` varchar(5) NOT NULL,
`bil` varchar(99) NOT NULL,
`sign` varchar(2) NOT NULL,
`tilldelad` varchar(12) NOT NULL,
`skapad` datetime NOT NULL,
`endrad` datetime NOT NULL,
`endrad_av` varchar(2) NOT NULL,
`kommentar` text NOT NULL,
`weektype` varchar(3) NOT NULL,
`Monday` tinyint(1) NOT NULL,
`Tuesday` tinyint(1) NOT NULL,
`Wednesday` tinyint(1) NOT NULL,
`Thursday` tinyint(1) NOT NULL,
`Friday` tinyint(1) NOT NULL,
`Saturday` tinyint(1) NOT NULL,
`Sunday` tinyint(1) NOT NULL,
`avbokad` varchar(2) NOT NULL,
`unika_kommentarer` varchar(2) NOT NULL,
UNIQUE KEY `bok_id` (`bok_id`)
Table B:
`id` int(6) NOT NULL AUTO_INCREMENT,
`bok_id` int(6) NOT NULL,
`tid` time NOT NULL,
`datum` date NOT NULL,
`datum_end` date NOT NULL,
`framtid` varchar(5) NOT NULL,
`h_adress` varchar(100) NOT NULL,
`l_adress` varchar(100) NOT NULL,
`kund` varchar(100) NOT NULL,
`typ` varchar(5) NOT NULL,
`bil` varchar(99) NOT NULL,
`sign` varchar(2) NOT NULL,
`tilldelad` varchar(12) NOT NULL,
`skapad` datetime NOT NULL,
`endrad` datetime NOT NULL,
`endrad_av` varchar(2) NOT NULL,
`kommentar` text NOT NULL,
`weektype` varchar(3) NOT NULL,
`Monday` tinyint(1) NOT NULL,
`Tuesday` tinyint(1) NOT NULL,
`Wednesday` tinyint(1) NOT NULL,
`Thursday` tinyint(1) NOT NULL,
`Friday` tinyint(1) NOT NULL,
`Saturday` tinyint(1) NOT NULL,
`Sunday` tinyint(1) NOT NULL,
`avbokad` varchar(2) NOT NULL,
`unika_kommentarer` varchar(2) NOT NULL,
UNIQUE KEY `id` (`id`)
What i want is a query which hides all rows in Table A which exists in table B IF Table B.tilldelad=Requested Date. (f.e 2013-09-30)
Im not sure this makes any sense?
What i want is to filter out period bookings as they have been executed and therefore exists in table b which indicates it has been.
Since its recurring events the same bok_id can exists SEVERAL times in table B, but only ONCE in table A...
SELECT * FROM bokningar
WHERE bokningar.datum <= '2013-09-30'
AND bokningar.datum_end >= '2013-09-30'
AND bokningar.typ >= '2'
AND bokningar.weektype = '1'
AND bokningar.Monday = '1' ## Monday this is dynamically changed to current date
AND bokningar.avbokad < '1'
AND NOT EXISTS ( SELECT 1 FROM tilldelade WHERE tilldelade.tilldelad = '2013-09-30' )
The above code does the trick regarding filtering out rows not in table B, however, if one row in table B has the current date, all results are filtered out.
Only rows with corresponding bok_id's is supposted to get filtered out.
Any thoughts on how to do that? Perhaps a Distinct select?
Typically, NOT IN subselects are quite expensive in querying time. This can normally be handled by doing a LEFT-JOIN and Keeping only those where the other table IS NULL like...
SELECT *
FROM
bokningar
LEFT JOIN tilldelade
on bokningar.bok_id = tilldelade.bok_id
AND tilldelade.tilldelad = '2013-09-30'
WHERE
bokningar.datum <= '2013-09-30'
AND bokningar.datum_end >= '2013-09-30'
AND bokningar.typ >= '2'
AND bokningar.weektype = '1'
AND bokningar.Monday = '1' ## Monday this is dynamically changed to current date
AND bokningar.avbokad < '1'
AND tilldelade.bok_id IS NULL
try something like
SELECT ...
FROM TABLEA
WHERE TABLEA.tilldelad=Requested Date
AND NOT EXISTS (SELECT 1 FROM TABLEB
WHERE TABLEB.tilldelad=Requested Date
AND TABLEA.bok_id = TABLEB.bok_id
AND...)
You need to do set operations.
A simple minus Query would solve your problem here.
Select * from tableA
minus
Select * from tableB;
This would display all data in tableA which is not present in tableB.
You can read more about it over here. http://en.wikipedia.org/wiki/Set_operations_%28SQL%29
For your specific case, try this :
Select * from tableA A
minus
Select * from tableB B where B.tilldelad='3013-09-30';

Slow update of one table when comparing multiple fields across two tables

The following query is timing out after 600 seconds.
update placed p
,Results r
set p.position = r.position
where p.competitor = r.competitor
AND p.date = r.date
AND REPLACE(p.time,":","") = r.time;
The structure is as follows:
'CREATE TABLE `placed` (
`idplaced` varchar(50) DEFAULT NULL,
`date` decimal(8,0) DEFAULT NULL,
`time` varchar(45) DEFAULT NULL,
`field1` varchar(45) DEFAULT NULL,
`competitor` varchar(45) DEFAULT NULL,
`field2` int(2) DEFAULT NULL,
`field3` varchar(45) DEFAULT NULL,
`field4` varchar(45) DEFAULT NULL,
`field5` decimal(6,2) DEFAULT NULL,
`field6` decimal(10,2) DEFAULT NULL,
`field7` decimal(6,2) DEFAULT NULL,
`field8` char(1) DEFAULT NULL,
`field9` varchar(45) DEFAULT NULL,
`position` char(4) DEFAULT NULL,
`field10` decimal(6,2) DEFAULT NULL,
`field11` char(1) DEFAULT NULL,
`field12` char(1) DEFAULT NULL,
`field13` decimal(6,2) DEFAULT NULL,
`field14` decimal(6,2) DEFAULT NULL,
`field15` decimal(6,2) DEFAULT NULL,
`field16` decimal(6,2) DEFAULT NULL,
`field17` decimal(6,2) DEFAULT NULL,
`field18` char(1) DEFAULT NULL,
`field19` char(20) DEFAULT NULL,
`field20` char(1) DEFAULT NULL,
`field21` char(5) DEFAULT NULL,
`field22` char(5) DEFAULT NULL,
`field23` int(11) DEFAULT NULL
PRIMARY KEY (`idplaced`),
UNIQUE KEY `date_time_competitor_field18_combo` (`date`,`time`,`competitor`,`field18`)
) ENGINE=InnoDB AUTO_INCREMENT=100688607 DEFAULT CHARSET=latin1;
CREATE TABLE `results` (
`idresults` int(11) NOT NULL AUTO_INCREMENT,
`date` char(8) DEFAULT NULL,
`time` char(4) DEFAULT NULL,
`field1` varchar(45) DEFAULT NULL,
`competitor` varchar(45) DEFAULT NULL,
`position` char(4) DEFAULT NULL,
`field2` varchar(45) DEFAULT NULL,
`field3` decimal(2,0) DEFAULT NULL,
PRIMARY KEY (`idresults`)
) ENGINE=InnoDB AUTO_INCREMENT=6644 DEFAULT CHARSET=latin1;
The PLACED table has 65,000 records, the RESULTS table has 9,000 records.
I am assuming the solution involves a JOIN statement of some descript, and I have tried taking several suggestions from this site, but am simply not finding the answer I am looking for. Simply put, I would be grateful for suggestions on this. I can put up example tables / create table code if requried.
The index cannot be used efficiently to perform the join because of your REPLACE operation.
I'd suggest creating an index with the columns in the following slightly different order:
(date, competitor, time, position)
It may also help to add this index on both tables.
It would be even better if you could modify the data in the database so that the data in the time column was stored in the same format in both tables.
First of all, you'd better send us your full tables description, using
show create table
Second, you'd better use join syntax :
update placed p
join Results r on r.competitor = p.competitor
set p.position = r.position
where p.date = r.date
AND REPLACE(p.time,":","") = r.time;
Hope this will help.