I know there are many examples of how to use this as well as links to the MySQL documentation. Unfortunately, I am still a in need of clarification on how it actually works.
For instance, The following table structure (SQL code) is one example of what I need to use the INSERT ... OR UPDATE:
CREATE TABLE IF NOT EXISTS `occt_category` (
`category_id` int(11) NOT NULL,
`image` varchar(255) DEFAULT NULL,
`parent_id` int(11) NOT NULL DEFAULT '0',
`top` tinyint(1) NOT NULL,
`column` int(3) NOT NULL,
`sort_order` int(3) NOT NULL DEFAULT '0',
`status` tinyint(1) NOT NULL,
`date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
ALTER TABLE `occt_category` ADD PRIMARY KEY (`category_id`);
ALTER TABLE `occt_category` MODIFY `category_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;
What I am attempting to insert into this mess are new categories from an API source so there are definitely duplicates.
What I am getting from the API is the following:
[
{
"categoryID": 81,
"name": "3/4 Sleeve",
"url": "3-4sleeve",
"image": "Images/Categories/81_fm.jpg"
}
]
So given the above information; Do I need to change my table structure to check for duplicates coming in from the API?
In MSSQL I would just simply do an IF EXISTS .... statement to check for duplicates. Unfortunately, this is MySQL :(.
If you intend to make use of the INSERT ... ON DUPLICATE KEY UPDATE MySQL Syntax (which is what I understand from your question, as INSERT ... OR UPDATE is not a real MySQL command), then your current table structure is fine and you will NOT have to check for duplicate records.
The way this works is that before writing any new records into your table, the MySQL DB will first check to see if there are any records that have a value in a PRIMARY or UNIQUE key-field (in your case category_id) that is the same value for the corresponding field in the incoming record, if it finds one, it will simply update that record as opposed to writing a new one.
You can read more about this syntax here.
Related
I have the following structure of the table:
`id` int(10) UNSIGNED NOT NULL,
`user_id` int(10) UNSIGNED NOT NULL,
`order` int(11) NOT NULL,
`category` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
I have five confirm records in table where i am querying table like this :
$recommended = App\Recommend::where('category', '=', 'editorpicks');
But the result comes empty, Let me paste the column name and value against it straight from DB.
column name : category
value : editorpicks.
Why its not working.
I have tried it in tinker also.
App\Recommend::where('category', 'editorpicks')->get();
Note, you don't need to use "=" in where, if no conditional is provided, the where clause will default to equals. get() grabs the collection. You could also do first() to grab first single record, last(), find($id), etc.
It's also good practice to namespace the model as well. So add use App\Recommend to top of controller (I'll assume this already makes sense) and then just use $recommended = Recommend::where(.... Keep things clean.
Here is my database mapping table definition,
you can try this, when I create this table and add some records in to it, it is not let me edit or delete the records by phpmyadmin although by query it should be possible,
CREATE TABLE IF NOT EXISTS `map2` (
`map_table_a` varchar(25) DEFAULT NULL,
`map_id_a` int(10) DEFAULT NULL,
`map_table_b` varchar(25) DEFAULT NULL,
`map_id_b` int(10) DEFAULT NULL,
KEY `map_table_b` (`map_table_b`,`map_id_b`),
KEY `map_table_a` (`map_table_a`,`map_id_a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I don't know reason behind this behavior
Depending on your phpMyAdmin version, you should see this error message:
While you do have KEY columns, you have no PRIMARY or UNIQUE columns defined. This is why phpMyAdmin cannot edit your data - it has no way to be sure it is editing the correct row.
Suggested solution: Add the following into your table definition, preferably as the first column:
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
I am working on a function that compares the date created and date modified of images and return the status of each case with PHP + MySQL. However, I realized that the data i'm trying to compare both end up using the CURRENT_TIMESTAMP in MySQL so whenever they are updated they end up having the same dates.
Is there a way to just only save the first date the data is inserted into the database (date created) so it doesn't change based on date modified?
Any help is appreciated, thanks in advance!
UPDATE:
my timestamp columns are configured using "DEFAULT CURRENT_TIMESTAMP" not the "ON UPDATE CURRENT_TIMESTAMP" option. Any other work arounds?
UPDATE2:
Please see below for my table definition.
CREATE TABLE IF NOT EXISTS `images` (
`id` varchar(50) NOT NULL,
`patientid` varchar(8) NOT NULL,
`caseid` varchar(25) NOT NULL,
`image_name` varchar(256) NOT NULL,
`status` int(1) unsigned NOT NULL,
`comments` varchar(4000) DEFAULT NULL,
`mod_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Seems like your timestamp columns are configured with "ON UPDATE CURRENT_TIMESTAMP" option, which automatically updates them.
As there does not seem a way to change this on a column, you have to create a new column without that option.
See the TIMESTAMP manual for details visit timestamp-initialization
I have imported 2 .csv file that I wanted to compare into MySQL table. now i want to compare both of them using join.
However, whenever I include both table in my queries, i get no response from phpMyAdmin ( sometimes it shows 'max execution time exceeded).
The record size in both db tables is 73k max. I dont think thats huge on data. Even a simple query like
SELECT *
FROM abc456, xyz456
seems to hang. I did an explain and I got this below. I dont know what to take from this.
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE abc456 ALL NULL NULL NULL NULL 73017
1 SIMPLE xyz456 ALL NULL NULL NULL NULL 73403 Using join buffer
can someone please help?
UPDATE: added the structure of the table with composite keys. There are around 100000+ records that would be inserted in this table.
CREATE TABLE IF NOT EXISTS `abc456` (
`Col1` varchar(4) DEFAULT NULL,
`Col2` varchar(12) DEFAULT NULL,
`Col3` varchar(9) DEFAULT NULL,
`Col4` varchar(3) DEFAULT NULL,
`Col5` varchar(3) DEFAULT NULL,
`Col6` varchar(40) DEFAULT NULL,
`Col7` varchar(200) DEFAULT NULL,
`Col8` varchar(40) DEFAULT NULL,
`Col9` varchar(40) DEFAULT NULL,
`Col10` varchar(40) DEFAULT NULL,
`Col11` varchar(40) DEFAULT NULL,
`Col12` varchar(40) DEFAULT NULL,
`Col13` varchar(40) DEFAULT NULL,
`Col14` varchar(20) DEFAULT NULL,
KEY `Col1` (`Col1`,`Col2`,`Col3`,`Col4`,`Col5`,`Col6`,`Col7`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
It looks like you are doing a pure catesian join in your query.
Shouldn't you be joining the tables on certain fields? If you do that and the query still takes a long time to execute, you should put appropriate indexes to speed up the query.
The reason that it is taking so long is that it is trying to join every single row of the first table to every single row of the second table.
You need a join condition, some way of identifying which rows should be matched up:
SELECT * FROM abc456, xyz456 WHERE abc456.id = xyz456.id
Add indexes on joining columns. That should help with performance.
Use MySQL Workbench or MySQL Client (console) for long queries. phpmyadmin is not designed to display queries that return 100k rows :)
If you REALLY have to use phpmyadmin and you need to run long queries you can use Firefox extension that prevents phpmyadmin timeout: phpMyAdmin Timeout Preventer (direct link!)
There is a direct link, because i couldnt find english description.
I'm looking for the most efficient solution to the problem I'm running into. I'm designing a shift calendar for our employees. This is the table I'm working with so far:
CREATE TABLE IF NOT EXISTS `Shift` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`accountId` smallint(6) unsigned NOT NULL,
`grpId` smallint(6) unsigned NOT NULL,
`locationId` smallint(6) unsigned NOT NULL,
`unitId` smallint(6) unsigned NOT NULL,
`shiftTypeId` smallint(6) unsigned NOT NULL,
`startDate` date NOT NULL,
`endDate` date NOT NULL,
`needFlt` bit(1) NOT NULL DEFAULT b'1',
`needBillet` bit(1) NOT NULL DEFAULT b'1',
`fltArr` varchar(10) NOT NULL,
`fltDep` varchar(10) NOT NULL,
`fltArrMade` bit(1) NOT NULL DEFAULT b'0',
`fltDepMade` bit(1) NOT NULL DEFAULT b'0',
`billetArrMade` bit(1) NOT NULL DEFAULT b'0',
`billetDepMade` bit(1) NOT NULL DEFAULT b'0',
`FacilityId` smallint(6) unsigned NOT NULL,
`FacilityWingId` mediumint(9) unsigned NOT NULL,
`FacilityRoomId` int(11) unsigned NOT NULL,
`comment` varchar(255) NOT NULL,
`creation` datetime NOT NULL,
`lastUpdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`lastUpdateBy` mediumint(9) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Now here's the hitch - I'd like to be able to display on the calendar (in a different color) whether or not a timesheet has been received for a certain day.
My first thought was to create a separate table and list separate entries by day for each employee, T/F. But the amount of data returned from a separate query, for each employee, for the whole month would surely be huge and inefficient.
Second thought was to somehow put the information in this Shift table, with delimiters - then exploding it with PHP. Silly idea... but I guess that's why im here. Any thoughts?
Thanks for your help!
As hinted previously and I think you realized yourself, serializing the data into a single column or using some other form of delimited string is a path to computational inefficiencies in the packing and unpacking and serious maintenance grief for the future.
Heaps better is to get the data structure right, i.e. a properly normalized table. After all, MySQL is rather good at dealing with this some of structure.
You don't need to pull back every line for every staff member. If you're pull them out together, you could "group" your resultset by employee and date, and even make that a potentially useful result by (say) pulling the summary of hours. A zero result or null result would show no timesheet, and the total hours may be helpful in some other way.
If you were pulling them out an employee and a date at a time then your application structure probably needs looking at, but you could use the SQL LIMIT keyword to pull at most one record and then test to see if any came back.