mysql IFNULL INSERT huge setback? - mysql

I am having a bit of a problem with some mysql. I will try to give a much background as I can. This is the situation, I had created an availability for my parent's plant nursery and stored the plant information in mysql, I did a terrible job the first time and now I am redoing it with the new knowledge I have gained in the mean time.
Background of the problem, I had 2 tables in the old database one being called Gallery with the following fields:
(id, Plant_id_1, Plant_id_2, Plant_id_3, Plant_id_4, Plant_id_5, Image1, Image1_Copyright, Image2, Image2_Copyright, Scientific, Common, Category, Height, Spread, Exposure, Zone, Descp).
The Plant_id_1... fields would be the id of the second table which is called Availability with the following fields:
(id, name, size, description, available, upcomming, price)
So as you can see I knew nothing about datases(still might not) but on to the new structure for the table, again 2 tables the first being called plants with the following fields:
(id, scientific_name, common_name, category, height, spread, exposure, usda, description, image1_url, image1_copyright, image2_url, image2_copyright)
The second being called current with the following fields:
(id, plant_id, size, available, upcoming, price, description)
The plant_id will be the id of the corresponding plant in the plant table.
Now on to the problem. I need to get the data from the old table and put it into the new table. I have all the plants from gallery in the new plant table no issue there. But now to get the Availability into the Current table.
This is an example from the export of the Availability (I took the top 3):
INSERT INTO `Availability` (`id`, `name`, `size`, `description`,`available`, `upcomming`, `price`) VALUES(91, 'Acer P.''Shishigashira''', ' #5', '30-36"', 27, 0, 36.00);
INSERT INTO `Availability` (`id`, `name`, `size`, `description`, `available`,`upcomming`, `price`) VALUES(697, 'Arbutus U. ''Compacta''', ' #5','', 0, 0, 16.20);
INSERT INTO `Availability` (`id`, `name`, `size`, `description`, `available`, `upcomming`, `price`) VALUES(90, 'Acer P.''Shigitatsusawa''', '#15', '', 0, 0, 65.00);
I need to get the plant_id from the plant table and put that into a insert statement, which I believe I have with the following:
INSERT INTO `current` (`plant_id`, `size`,`description`, `available`, `upcoming`, `price`) VALUES(
(SELECT `id`
FROM `plants`
WHERE `scientific_name`
REGEXP 'Acer P.+ ''Shishigashira'''), ' #5', '30-36"', 27, 0, 36.00);
But now I have a new problem what if there is no plant in the plant table to match, So i need a ifnull in there. to create the plant with the scientific name and the rest null. well I am new to SQL so this is what I have and its not working:
INSERT INTO `current` (`plant_id`, `size`,`description`, `available`, `upcoming`, `price`) VALUES(
(IFNULL( SELECT IFNULL( (SELECT `id`
FROM `plants`
WHERE `scientific_name`
REGEXP 'Chamaecyparis O.+ Nana'),(
INSERT INTO `plants` (`scientific_name`)
VALUES (Chamaecyparis O. 'Nana'))))), ' #1', '', 0, 0, 9.25);
As you can see Its very complicated if you think you are up to the challenge of helping me i would beyond greatly appreciated. If no one can help me I will have to manually reenter all the data into the current table.

You should work towards a select that returns the data you need to insert into your new table. Once
you have that you can simply wrap that into a INSERT INTO - SELECT contruction. That way you don't have to export and do individual inserts. You can simply copy the whole set over in one go.
If you make sure that when you copy plants from the gallery into the plants table the id's stay intact I expect a select like this should return the rows you want to insert:
SELECT
Gallery.id as plant_id,
Availability.size,
Availability.available,
Availability.upcoming,
Availability.price,
Availability.description
FROM Gallery
INNER JOIN Availability
ON Gallery.Plant_id1 = Availability.id
Then you can do the same thing 5 times where you change the
ON Gallery.Plant_id1 = Availability.id
to (one by one)
ON Gallery.Plant_id2 = Availability.id
ON Gallery.Plant_id3 = Availability.id
ON Gallery.Plant_id4 = Availability.id
ON Gallery.Plant_id5 = Availability.id
Or you put all of them together in one huge sql statement with a UNION ALL between each select

Related

How can I use values from one database to insert them into a table in another database?

I want to insert multiple values from one database into another.
INSERT IGNORE INTO organization (`id`, `company_id`, `code`, `name`, `path`)
(SELECT 100 + id_status FROM database2.employeestatus), '1',
(SELECT 100 + id_status FROM database2.employeestatus),
(SELECT tagline FROM database2.employeestatus),
(SELECT 100 + id_status FROM database2.employeestatus);
The issue is that when I try to run it this way, it breaks, ofc. But when I execute it one by one, for example:
SELECT 100 + id_status FROM database2.employeestatus
Then it returns all rows I need. There are about 40 rows, and I don't want to enter them manually.
Can someone please help me with this?
Try using an INSERT INTO ... SELECT:
INSERT IGNORE INTO organization (id, company_id, code, name, path)
SELECT 100 + id_status, '1', 100 + id_status, tagline,
100 + id_status
FROM database2.employeestatus;
The problem with your current approach is that each of the subqueries you have in the select clause themselves return more than one record/value. This doesn't make sense as a select list can only contain single scalar values.

Insert Into query broken in mysql

I need to run this kind of query.
INSERT INTO `book_newBookOrder` (id, volume, 5, chapterNr, sectionNr, `text`)
SELECT id, volume, bookNr, chapterNr, sectionNr, `text`
FROM book_oldBookOrder
WHERE booknr = 1;
The fixed value 5 in the INSERT INTO part breaks it.
I must be able to specify the two values as above.
So I want to select everything with bookNr = 1 in the oldbooknr table and store that as booknr 5 in the newbookorder table.
Please advise me. Thanks.
You have a syntax error: The items in the first set of brackets in the INSERT should be the field names. "5" is not a field name, that's the value you want to be inserted (I assume you wish to set this value the same in every row which gets inserted?). That should be in the SELECT:
INSERT INTO `book_newBookOrder` (id, volume, bookNr, chapterNr, sectionNr, `text`)
SELECT id, volume, 5, chapterNr, sectionNr, `text`
FROM book_oldBookOrder
WHERE booknr = 1;

Trouble understanding how to create a Join & Require query

So, I guess I should explain what I mean by a Join & Require Query as this probably isn't the correct term. For this question I set up a very simple subset of tables that would be out of a wireframe for a video game. I apologise in advance, SQLFiddle isn't working right now.
CREATE TABLE reqs (
crafted_id INT, item_id INT );
CREATE TABLE items (
id INT, name VARCHAR(30) );
CREATE TABLE crafted (
id INT, name VARCHAR(30) );
With these tables, I also created some sample data. I didn't use auto_increment in these tables so you could have a better visual.
INSERT INTO items (id, name) VALUES (1, 'Herbs');
INSERT INTO items (id, name) VALUES (2, 'Health Potion');
INSERT INTO items (id, name) VALUES (3, 'Leather');
INSERT INTO items (id, name) VALUES (4, 'Sticks');
INSERT INTO crafted (id, name) VALUES (101, 'Cured Leather');
INSERT INTO crafted (id, name) VALUES (102, 'Tea');
INSERT INTO reqs (crafted_id, item_id) VALUES (101, 1);
INSERT INTO reqs (crafted_id, item_id) VALUES (101, 3);
INSERT INTO reqs (crafted_id, item_id) VALUES (102, 1);
In this example I have setup a very minimalistic example of a crafting system in a game, where a crafted item requires other items.
I need to create a query in which I can pull all of the available values from the crafted table based on the items that I have. For example, based on the data above, I would do the following:
requestCraftableItems(itemArray) {
// Execute query based on array here
};
requestCraftableItems([1, 2, 3])
This should execute a query stating that the user has items 1, 3, & 4 and try to find a crafted entry where all of the reqs.item_id for reqs.crafted_id are met in the item array. In this example nothing should be returned, because the crafted_id for cured leather requires items 1 & 3 and the crafted_id for tea requires item 1
So if the user executed the following:
requestCraftableItems([1, 3, 4]);
It should return the crafted entry for Cured Leather AND Tea as the user supplied 1 & 3 to the query.
This is not my originally use case and is just an example to get the point of what I'm trying to do across on a very simple scale.
EDIT: To clairfy, if the value (1) is passed to the query, Cured Leather should not appear in the results, as Cured Leather requires BOTH 1 and 3.
I may have misunderstood what you are looking for, but a simple join should return the result you want:
SELECT crafted.name
FROM items
JOIN reqs
ON reqs.item_id = items.id
JOIN crafted
ON crafted.id = reqs.crafted_id
WHERE items.id in (1,3,4)
GROUP BY crafted.id
This would return the results in your examples.
Not tested, may contain typos

Insert record into table with position without updating all the records position field

I am using MySQL, I don't have a good way to do this.
I have a table with a position field, which I need to keep track having values from 1 to 10,000.
Let's say I insert a record in the middle at 5000th position. So position 5000 to 10,000 need to be updated to the new position; old 5000 become 5001, 5002 becomes 5003...
Is there a good way to implement this without affecting so many records, when 1 single position is added?
Adding from the position 1st is the worst.
I'd rethink the database design. If you're going to be limited to on the order of 10K records then it's not too bad, but if this is going to increase without bound then you'll want to do something else. I'm not sure what you are doing but if you want a simple ordering (assuming you're not doing a lot of traversal) then you can have a prev_id and next_id column to indicate sibling relationships. Here's the answer to your questions though:
update some_table
set some_position = some_position + 1
where some_position > 5000 and some_position < 10000
You can try the below approach :
USE tempdb;
GO
CREATE TABLE dbo.Test
(
ID int primary key clustered identity(1,1) ,
OrderNo int,
CreatedDate datetime
);
--Insert values for testing the approach
INSERT INTO dbo.Test
VALUES
(1, GETUTCDATE()),
(2, GETUTCDATE()),
(3, GETUTCDATE()),
(4, GETUTCDATE()),
(5, GETUTCDATE()),
(6, GETUTCDATE());
SELECT *
FROM dbo.Test;
INSERT INTO dbo.Test
VALUES
(3, GETUTCDATE()),
(3, GETUTCDATE());
SELECT *
FROM dbo.Test;
--To accomplish correct order using ROW_NUMBER()
SELECT ID,
OrderNo,
CreatedDate,
ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
FROM dbo.Test;
--Again ordering change
INSERT INTO dbo.Test
VALUES
(3, GETUTCDATE()),
(4, GETUTCDATE());
SELECT ID,
OrderNo,
CreatedDate,
ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
FROM dbo.Test
DROP TABLE dbo.Test;

Multiple insert in multiple tables if nonindexed field not exists

I have a task to update existing multiple product-related tables with new entries if product name doesn't exist (no update). Thing is that this is one time action so product name column is not and will not be set as unique, primary, etc (and it is not possible for me to change it anyway).
I would be delighted if i could access the database remotely and use PHP, but due to security reasons i have access only to PhpMyAdmin on that server.
After googling for couple of hours i realized that either all results are about single INSERT IGNORE or similar constructions, or they are too complicated for me non-mysql brain to understand or solutions just won't work (like IF statement throws syntax error on that 5.5.8 MySQL server.
So thing is - there are 7 tables with all kinds of information on product (product, variant, image, category, product relation to category, prices, discounts). I have to check if product name doesn't exist and if true then insert new entries in all 7 tables. Additionaly i should create new product category entry if such doesn't exist (again, by name, not id)
In my humble opinion it would be like this:
IF (SELECT ProductName from `product` where ProductName='Pony') IS NULL THEN
INSERT INTO `product` VALUES ('', 'Pony');
#productId = (SELECT LAST_INSERT_ID());
INSERT INTO `category` (Name) SELECT 'Everything Nice' FROM `category` WHERE NOT EXISTS (SELECT Name FROM `category` WHERE Name='Everything Nice') LIMIT 1;
SET #categoryId = (SELECT CategoryId FROM `category` WHERE Name='Everything Nice');
INSERT INTO `product_rel_category` VALUES (#productId, #categoryId);
INSERT INTO `variant` VALUES ('', 'Nice');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
INSERT INTO `variant` VALUES ('', 'Sweet');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
INSERT INTO `variant` VALUES ('', 'Pink');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
... etc ...
ENDIF;
MySQL yells about syntax on IF in such query. I also tried working all kinds of procedures, but since I know only 'insert, update, select, delete', there is nothing much i can compose now.
So do you have an advise on solution on how i can make multiple INSERT/SELECT queries if a value in one table doesn't exist.
Sincerely thanks.