I have 2 MySQL tables. One is pastsergicalhistory_type and the other one is pastsurgicalhistory
Below is pastsergicalhistory_type
CREATE TABLE `pastsergicalhistory_type` (
`idPastSergicalHistory_Type` int(11) NOT NULL AUTO_INCREMENT,
`idUser` int(11) DEFAULT NULL,
`Name` varchar(45) NOT NULL,
PRIMARY KEY (`idPastSergicalHistory_Type`),
KEY `fk_PastSergicalHistory_Type_User1_idx` (`idUser`),
CONSTRAINT `fk_PastSergicalHistory_Type_User1` FOREIGN KEY (`idUser`) REFERENCES `user` (`idUser`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
Below is pastsurgicalhistory
CREATE TABLE `pastsurgicalhistory` (
`idPastSurgicalHistory` int(11) NOT NULL AUTO_INCREMENT,
`idPatient` int(11) NOT NULL,
`idPastSergicalHistory_Type` int(11) NOT NULL,
`Comment` varchar(45) DEFAULT NULL,
`ActiveStatus` tinyint(1) NOT NULL,
`LastUpdated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`idPastSurgicalHistory`),
KEY `fk_PastSurgicalHistory_Patient1_idx` (`idPatient`),
KEY `fk_PastSurgicalHistory_PastSergicalHistory_Type1_idx` (`idPastSergicalHistory_Type`),
CONSTRAINT `fk_PastSurgicalHistory_PastSergicalHistory_Type1` FOREIGN KEY (`idPastSergicalHistory_Type`) REFERENCES `pastsergicalhistory_type` (`idPastSergicalHistory_Type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_PastSurgicalHistory_Patient1` FOREIGN KEY (`idPatient`) REFERENCES `patient` (`idPatient`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
Now my requirement is as this, I will explain it in point form.
Get all the data from pastsergicalhistory_type where idUser is NULL or idUser is 1.
Get all the data from pastsurgicalhistory where idPatient is 2.
as you can see, the foreign key of pastsurgicalhistory is the primary key of pastsergicalhistory_type.
I tried the below query, but it gave me the wrong results. It only displayed what is available in pastsurgicalhistory. The data in pastsergicalhistory_type (which follows the condition in point 1) which is not in pastsurgicalhistory is not displayed.
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
WHERE pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1 AND pastsurgicalhistory.idPatient=2
So, how can I solve this problem?
EDIT
If I use the AND pastsurgicalhistory.idPatient=2 in my where clause, it actually filters the "entire" result set. This will give me results where idPatient is related to 2. But as I mentioned, I need data which is not available in pastsurgicalhistory table as well.
Try
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON
(pastsurgicalhistory.`idPastSergicalHistory_Type` =
pastsergicalhistory_type.`idPastSergicalHistory_Type` and
pastsurgicalhistory.idPatient=2)
WHERE (pastsergicalhistory_type.idUser = NULL OR
pastsergicalhistory_type.idUser=1) ;
Move pastsurgicalhistory.idPatient=2 to join condition
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
AND pastsurgicalhistory.idPatient=2
WHERE pastsergicalhistory_type.idUser IS NULL OR pastsergicalhistory_type.idUser=1
Use paraenthises?
WHERE pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1 AND pastsurgicalhistory.idPatient=2
I belive would return results where idUser is 1 and idPatient is 2 or iduser is null
Try this:
WHERE (pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1) AND pastsurgicalhistory.idPatient=2
If I understand you correctly?
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
RIGHT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
WHERE (pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1) AND pastsurgicalhistory.idPatient=2
Even if it works without parenthesis for you, I would say it's better to use to make it more readable.
Related
I am creating an inventory management app in node.js that uses MySQL as a database. I have a weak entity “rental_item” that holds the items in a particualr rental. The issue is that the rental may not come back all at once so I need a way of marking the “rental_returned” boolean in the rental table true only when all of the “item_returned” entires are true.
Here is my table structure:
CREATE TABLE `rental` (
`rental_id` int NOT NULL AUTO_INCREMENT,
`renter_id` int NOT NULL,
`date_in` date NOT NULL,
`date_out` date NOT NULL,
`sig_path` varchar(50) NOT NULL,
`doc_path` varchar(50) NOT NULL,
`col_name` varchar(50) NOT NULL,
`col_path` varchar(50) NOT NULL,
`cost` decimal(15,2) NOT NULL,
`rental_returned` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`rental_id`),
UNIQUE KEY `doc_path` (`doc_path`),
UNIQUE KEY `col_path` (`col_path`),
UNIQUE KEY `sig_path` (`sig_path`),
KEY `renter_key` (`renter_id`),
CONSTRAINT `renter_key` FOREIGN KEY (`renter_id`) REFERENCES `renter` (`renter_id`)
)
CREATE TABLE `rental_item` (
`rental_id` int NOT NULL,
`i_ID` varchar(20) NOT NULL,
`item_returned` tinyint(1) NOT NULL DEFAULT '0',
KEY `rental_key` (`rental_id`),
KEY `rental_item_key` (`i_ID`),
CONSTRAINT `rental_item_key` FOREIGN KEY (`i_ID`) REFERENCES `item` (`i_ID`),
CONSTRAINT `rental_key` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE CASCADE
)
I am currently doing this through the mysql2 node.js module and just checking for all the values of a given rental_id. I then found out about triggers and thought this way could be better. I fiddled round with things like this Trigger with table join, but couldn’t wrap my head around how to get the rental_id of the entry that was updated from rental_item, then check that all entires in rental_item with that id have item_returned = 1, and finally update the rental table to show that all the items/the complete rental has been returned.
I understand that this sould be an update after trigger on rental_item but dont know how to handle the conditionals or loops needed.
Use NEW.rental_id to get the ID of the row that was updated.
CREATE TRIGGER rental_returned AFTER UPDATE ON rental_item
FOR EACH ROW
UPDATE rental
SET rental_returned = (
NOT EXISTS (
SELECT *
FROM rental_item
WHERE rental_id = NEW.rental_id
AND item_returned = 0))
WHERE rental_id = NEW.rental_id
This query takes around 2.23seconds and feels a bit slow ... is there anyway to make it faster.
our member.id, member_id, membership_id, valid_to, valid_from has index as well.
select *
from member
where (member.id in ( select member_id from member_membership mm
INNER JOIN membership m ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
EXPLAIN FOR WHAT QUERY DOING: every member has many a member_memberships and and member_memberships connect with another table called membership there we have the membership details. so query will get all members that has valid memberships and where the organization id 2513 exist on member_membership.
Tables as following:
CREATE TABLE `member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
CREATE TABLE `member_membership` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`membership_id` int(11) DEFAULT NULL,
`member_id` int(11) DEFAULT NULL,
`organization_chain` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `member_membership_to_membership` (`membership_id`),
KEY `member_membership_to_member` (`member_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
CREATE TABLE `membership` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`valid_to` datetime DEFAULT NULL,
`valid_from` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `valid_to` (`valid_to`),
KEY `valid_from` (`valid_from`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
ALTER TABLE `member_membership` ADD CONSTRAINT `member_membership_to_membership` FOREIGN KEY (`membership_id`) REFERENCES `membership` (`id`);
ALTER TABLE `member_membership` ADD CONSTRAINT `member_membership_to_member` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`);
Here with EXPLAIN statement => https://i.ibb.co/xjrcYWR/EXPLAIN.png
Relations
member has many member_membership
membership has manymember_membership
So member_membership is like join for tables member and membership.
Well I found a way to make it less to 800ms ... like this. Is this good way or maybe there is more we can do?
select *
from member
where (member.id in ( select member_id from member_membership mm FORCE INDEX (PRIMARY)
INNER JOIN membership m ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
NEW UPDATE.. and I think this solve the issue.. 15ms :)
I added FORCE INDEX..
The FORCE INDEX hint acts like USE INDEX (index_list), with the addition that a table scan is assumed to be very expensive. In other words, a table scan is used only if there is no way to use one of the named indexes to find rows in the table.
select *
from member
where (member.id in ( select member_id from member_membership mm FORCE INDEX (member_membership_to_member)
INNER JOIN membership m FORCE INDEX (organization_to_membership) ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
How big is organization_chain? If you don't need TEXT, use a reasonably sized VARCHAR so that it could be in an index. Better yet, is there some way to get 2513 in a column by itself?
Don't use id int(11) NOT NULL AUTO_INCREMENT, in a many-to-many table; rather have the two columns in PRIMARY KEY.
Put the ORDER BY and LIMIT in the subquery.
Don't use IN ( SELECT ...), use a JOIN.
I have a MySQL DB. Acquired data are stored in raw_data_headers, raw_data_rows and raw_data_row_details table.
raw_data_row_details has a foreign key that reference raw_data_rows.ID, the same for raw_data_rows and raw_data_headers.
In raw_data_headers are stored data headers, in raw_data_rows are stored every stage of acquisition program and in raw_data_row_details are stored details for each stage of acquisition program.
This is the query:
SELECT
q1.ProcessTypeID,
q1.TestTypeID,
q1.ComponentID,
q1.TestResultID,
COUNT(*) AS Counter
FROM (
SELECT
raw_data_headers.batch_id AS BatchID,
raw_data_test_outputs.test_output_type_id AS TestOutputTypeID,
raw_data_test_types.process_type_id AS ProcessTypeID,
raw_data_test_types.ID AS TestTypeID,
raw_data_row_details.component_id AS ComponentID,
raw_data_test_results.ID AS TestResultID
FROM raw_data_row_details
INNER JOIN raw_data_rows ON raw_data_rows.ID = raw_data_row_details.row_id
INNER JOIN raw_data_headers ON raw_data_headers.ID = raw_data_rows.header_id
INNER JOIN raw_data_test_results ON raw_data_test_results.ID = raw_data_row_details.Value
INNER JOIN raw_data_test_outputs ON raw_data_test_outputs.ID = raw_data_row_details.test_output_id
INNER JOIN raw_data_test_types ON raw_data_test_types.ID = raw_data_test_outputs.test_type_id
HAVING TestOutputTypeID = 2 AND BatchID = 1
) AS q1
GROUP BY q1.ProcessTypeID, q1.TestTypeID, q1.ComponentID, q1.TestResultID
raw_data_headers has 989'180 entries, row_data_rows has 2'967'540 entries and raw_data_row_details has 13'848'520 entries.
The subquery q1 take about 3 minutes, but final query takes about 25 minutes. I think that the point is in the GROUP BY.
How can I improve performance?
EDIT 1:
SELECT
gnuhmi.raw_data_test_types.process_type_id AS ProcessTypeID,
gnuhmi.raw_data_test_types.ID AS TestTypeID,
gnuhmi.raw_data_row_details.component_id AS ComponentID,
gnuhmi.raw_data_test_results.ID AS TestResultID,
COUNT(*) AS Counter
FROM gnuhmi.raw_data_row_details
INNER JOIN gnuhmi.raw_data_rows ON gnuhmi.raw_data_rows.ID = gnuhmi.raw_data_row_details.row_id
INNER JOIN gnuhmi.raw_data_headers ON gnuhmi.raw_data_headers.ID = gnuhmi.raw_data_rows.header_id
INNER JOIN gnuhmi.raw_data_test_results ON gnuhmi.raw_data_test_results.ID = gnuhmi.raw_data_row_details.Value
INNER JOIN gnuhmi.raw_data_test_outputs ON gnuhmi.raw_data_test_outputs.ID = gnuhmi.raw_data_row_details.test_output_id
INNER JOIN gnuhmi.raw_data_test_types ON gnuhmi.raw_data_test_types.ID = gnuhmi.raw_data_test_outputs.test_type_id
WHERE gnuhmi.raw_data_test_outputs.test_output_type_id = 2 AND gnuhmi.raw_data_headers.batch_id = 1
GROUP BY
gnuhmi.raw_data_test_results.ID,
gnuhmi.raw_data_row_details.component_id,
gnuhmi.raw_data_test_types.ID,
gnuhmi.raw_data_test_types.process_type_id
This is the new query, without subquery and WHERE. This increased performance (thanks #Yogesh Sharma).
this is raw_data_headers structure:
CREATE TABLE `raw_data_headers` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Univocal record key',
`ProductID` int(11) NOT NULL COMMENT 'Product numeric ID',
`Datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Univocal record creation date',
`batch_id` int(11) DEFAULT NULL COMMENT 'Univocal batch key',
`RecipeName` varchar(80) DEFAULT NULL COMMENT 'Used recipe name',
`RecipeVersion` smallint(6) DEFAULT NULL COMMENT 'Used recipe version',
`process_result_id` smallint(6) DEFAULT NULL COMMENT 'Process result key',
`invalidated` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'invalidation after counters reset',
PRIMARY KEY (`ID`),
KEY `FK_raw_data_headers_batches_ID` (`batch_id`),
KEY `FK_raw_data_headers_process_re` (`process_result_id`),
CONSTRAINT `FK_raw_data_headers_batches_ID` FOREIGN KEY (`batch_id`) REFERENCES `batches` (`ID`) ON UPDATE CASCADE,
CONSTRAINT `FK_raw_data_headers_process_re` FOREIGN KEY (`process_result_id`) REFERENCES `process_result` (`ID`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stores raw data headers'
This the raw_dato_rows:
CREATE TABLE `raw_data_rows` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Univocal record key',
`Datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Univocal record creation date',
`header_id` int(11) unsigned NOT NULL COMMENT 'Univocal raw data header key',
`process_type_id` smallint(6) NOT NULL COMMENT 'Univocal process type key',
`process_result_id` smallint(6) NOT NULL COMMENT 'Univocal process result key',
PRIMARY KEY (`ID`),
KEY `FK_raw_data_rows_header_id` (`header_id`),
KEY `FK_raw_data_rows_process_resu2` (`process_result_id`),
KEY `FK_raw_data_rows_process_resul` (`process_type_id`),
CONSTRAINT `FK_raw_data_rows_header_id` FOREIGN KEY (`header_id`) REFERENCES `raw_data_headers` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_raw_data_rows_process_resu2` FOREIGN KEY (`process_result_id`) REFERENCES `process_result` (`ID`) ON DELETE NO ACTION ON UPDATE CASCADE,
CONSTRAINT `FK_raw_data_rows_process_resul` FOREIGN KEY (`process_type_id`) REFERENCES `process_types` (`ID`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2967541 DEFAULT CHARSET=utf8 COMMENT='Stores row data rows'
and finally this is the raw_data_row_details one:
CREATE TABLE `raw_data_row_details` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Univocal row detail key',
`row_id` int(11) unsigned NOT NULL COMMENT 'Univocal row key',
`test_output_id` int(11) NOT NULL COMMENT 'Univocal test output key',
`component_id` int(11) NOT NULL COMMENT 'The component that take the measurement',
`Value` double NOT NULL COMMENT 'Output value',
PRIMARY KEY (`ID`),
KEY `FK_raw_data_row_details_row_id` (`row_id`),
KEY `FK_raw_data_rows_raw_data_test_outputs_ID` (`test_output_id`),
KEY `raw_data_row_details_components_FK` (`component_id`),
CONSTRAINT `FK_raw_data_row_details_row_id` FOREIGN KEY (`row_id`) REFERENCES `raw_data_rows` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_raw_data_rows_raw_data_test_outputs_ID` FOREIGN KEY (`test_output_id`) REFERENCES `raw_data_test_outputs` (`ID`) ON UPDATE CASCADE,
CONSTRAINT `raw_data_row_details_components_FK` FOREIGN KEY (`component_id`) REFERENCES `components` (`ID`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13848521 DEFAULT CHARSET=utf8 COMMENT='Stores raw data rows details'
You don't need to use subquery, just use where clause with group by :
SELECT raw_data_test_types.process_type_id AS ProcessTypeID,
raw_data_test_types.ID AS TestTypeID,
raw_data_row_details.component_id AS ComponentID,
raw_data_test_results.ID AS TestResultID, COUNT(*) AS Counter
FROM raw_data_row_details INNER JOIN
raw_data_rows
ON raw_data_rows.ID = raw_data_row_details.row_id INNER JOIN
raw_data_headers
ON raw_data_headers.ID = raw_data_rows.header_id INNER JOIN
raw_data_test_results
ON raw_data_test_results.ID = raw_data_row_details.Value INNER JOIN
raw_data_test_outputs
ON raw_data_test_outputs.ID = raw_data_row_details.test_output_id INNER JOIN
raw_data_test_types
ON raw_data_test_types.ID = raw_data_test_outputs.test_type_id
WHERE raw_data_headers.batch_id = 1 AND raw_data_test_outputs.test_output_type = 2
GROUP BY raw_data_test_types.process_type_id, raw_data_test_types.ID,
raw_data_row_details.component_id, raw_data_test_results.ID;
Add indexes. TestOutputTypeID and BatchID need to be covered and probably are not.
To see what's currently going on, use EXPLAIN in the MySQL console. You will probably see an indication that a full table scan is happening i.e. the join type is marked as ALL.
It's often the case that the query optimiser will use the same execution plan for different queries e.g. by expanding the subquery as if you hadn't used it. Only EXPLAIN will show you what's what.
Here's the docs on how to interpret the EXPLAIN output: https://dev.mysql.com/doc/refman/8.0/en/explain-output.html
HAVING TestOutputTypeID = 2 AND BatchID = 1
Change that from HAVING to WHERE, and have indexes in each of those columns.
Also have these indexes:
raw_data_row_details: (row_id)
raw_data_rows: (header_id)
raw_data_row_details: (test_output_id)
raw_data_test_outputs: (test_type_id)
Get rid of raw_data_ from the table names; it just clutters the queries.
If those do not help enough, please provide EXPLAIN SELECT ... and SHOW CREATE TABLE.
How can I query for all records in a table called photos, and know which of the resulting photos have been bookmarked by the current user using a single query?
Here are my tables:
--
-- Table structure for table `photos`
--
CREATE TABLE IF NOT EXISTS `photos` (
`id` int(11) NOT NULL auto_increment,
`author` bigint(20) NOT NULL COMMENT 'The user''s Facebook ID.',
`filename` varchar(255) NOT NULL,
`thumbnail` varchar(255) NOT NULL,
`post_date` timestamp NOT NULL default CURRENT_TIMESTAMP,
`description` varchar(140) NOT NULL,
`finalist` tinyint(4) NOT NULL DEFAULT '0',
CONSTRAINT user_must_exist FOREIGN KEY (author)
REFERENCES users(facebook_id)
ON DELETE CASCADE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `bookmarks`
--
CREATE TABLE IF NOT EXISTS `bookmarks` (
`facebook_id` bigint(20) NOT NULL COMMENT 'The author''s Facebook ID.',
`photo_id` int(11) NOT NULL,
CONSTRAINT photo_should_exist FOREIGN KEY (photo_id)
REFERENCES photos(id)
ON DELETE CASCADE,
CONSTRAINT user_should_exist FOREIGN KEY (facebook_id)
REFERENCES users(facebook_id)
ON DELETE CASCADE,
UNIQUE KEY `no_duplicates` (`facebook_id`,`photo_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='The user''s favourite photos.';
I would imagine this query would look something like the following:
SELECT
photos.*,
bookmarks.photo_id AS bookmark
FROM photos
LEFT JOIN bookmarks
ON bookmarks.photo_id = photos.id
AND photos.author = 123456789
However this doesn't work and I receive the following MySQL error:
Unknown column 'photos.id' in 'on clause'
keyur's code worked for me after a minor typo fix which Barmar pointed out.
SELECT photos . * , bookmarks.photo_id AS bookmark
FROM photos
LEFT JOIN bookmarks ON photos.id = bookmarks.photo_id
AND bookmarks.facebook_id = 123456789
Thank you.
Editted for typo.
Editted for second typo.
Here is a sample working code on SQL Fiddle. As pointed out on a comment, you do not have a bookmarks.id column on you bookmarks table and photo.id indeed exists on the photos table. Check again the error you are receiving as seems something is not correct.
you query should be like this.
SELECT
photos.*,
bookmarks.id AS bookmark
FROM photos
LEFT JOIN bookmarks
ON photos.id = bookmarks.photo_id
AND bookmarks.facebook_id = 123456789
according your table structure photos.facebook_id is not exist; it is in bookmarks table
Having some troubles with ON DUPLICATE KEY UPDATE in MySQL. Below is the query im trying to run.
INSERT INTO `Overall` ( `rsn` , `starting_xp` , `starting_lvl` ) VALUES ( 'iWader' , '195843626' , '2281' ) ON DUPLICATE KEY UPDATE `current_xp` = '195843626' AND `current_lvl` = '2281'
It inserts fine, but when there is a duplicate it doesnt update, and doesnt throw any errors.
Running the query through PMA returns no error and doesnt update
Removing the ON DUPLICATE KEY UPDATE section returns a duplicate key error
This is the structure of my table
CREATE TABLE IF NOT EXISTS `overall` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rsn` varchar(12) NOT NULL,
`starting_xp` int(10) unsigned NOT NULL,
`starting_lvl` int(10) unsigned NOT NULL,
`current_xp` int(10) unsigned NOT NULL,
`current_lvl` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `rsn` (`rsn`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
After ON DUPLICATE KEY UPDATE you should not need to use and with the fields, use , instead.
ON DUPLICATE KEY UPDATE `current_xp` = '195843626', `current_lvl` = '2281'
Try this:
INSERT INTO `Overall` ( `rsn` , `starting_xp` , `starting_lvl` ) VALUES ( 'iWader' , '195843626' , '2281' ) ON DUPLICATE KEY UPDATE `current_xp` = '195843626', `current_lvl` = '2281';
The AND in your UPDATE clause is wrong. The AND is used in boolean expressions like "is foo true AND bar true?"
Here you want to update column current_xp, current_lvl.