I have a table with column
merchant_id | phone
1 | 879182782
2 | 324239324
now what i want is a query to insert multiple values for phone field
merchant_id | phone
1 | 879182782,989838273
2 | 324239324,849238420,349289393
Can anyone help me with example query? I tried update and all but couldn't work
I agree with Gordon, but with you want anyway, you can use "CONCAT", here an example for you:
create table tabla(
merchant_id int AUTO_INCREMENT PRIMARY KEY,
phone text
);
insert into tabla(merchant_id,phone)
VALUES (1,'809-541-8935');
insert into tabla(merchant_id,phone)
VALUES (2,'809-541-8935');
insert into tabla(merchant_id,phone)
VALUES (3,'809-541-8935');
UPDATE tabla
SET phone = concat(phone, ',809-537-7791')
where merchant_id = 1
DEMO
Related
I have search already an answer but i can't find one that is good for my situation.
I have a table called Names like this
ID NAME Age
1 Paula 20
2 Mark 17
And i want to run this sql
Insert into table names(name,age) values ("Chriss",15)//should be inserted
Insert into table names(name,age) values ("Mark",17)// should be ignored
Insert into table names(name,age) values ("Andrea",20) //should be inserted
So how can I ignore second insert query
Create a constraint that demands NAME and Age to be unique in the table.
ALTER TABLE `tablename` ADD UNIQUE `unique_index`(`NAME`, `Age`);
You would either need to Add UNIQUE constraint or check the data at the run time (if you don't have a permission to change table schema):
ALTER TABLE `Table_name`
ADD UNIQUE INDEX (`NAME`, `AGE`);
You can use:
INSERT INTO names(name,age)
SELECT * FROM (SELECT 'Chriss', 15) AS tmp
WHERE NOT EXISTS (
SELECT name FROM names WHERE name = 'Chriss' AND age = 15
) LIMIT 1;
An other way is just make the columns name and age UNIQUE so the query fails.
Change your query to this:
Insert into table names(name,age)
SELECT "Chriss",15 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Chriss");
Insert into table names(name,age)
SELECT "Mark",17 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Mark");
Insert into table names(name,age)
SELECT "Andrea",20 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Andrea");
First create a unique constraint for the columns NAME and Age:
ALTER TABLE names ADD UNIQUE un_name_age (`NAME`, `Age`);
and then use INSERT IGNORE to insert the rows:
Insert ignore into names(name,age) values
("Chriss",15),
("Mark",17),
("Andrea",20);
So if you try to insert a duplicate name the error will just be ignored and the statement will continue with the next row to insert.
See the demo.
Result:
| ID | NAME | Age |
| --- | ------ | --- |
| 1 | Paula | 20 |
| 2 | Mark | 17 |
| 3 | Chriss | 15 |
| 4 | Andrea | 20 |
I am new to MYSQL and would like to create a table where a constant Letter depicting the department is added to an auto increment number. This way I would be able to identify the category of the worker upon viewing the ID.
Ex. Dept A and employee 135. The ID I am imaging should read A135 or something similar. I have created the table, the auto increment works fine, the constant letter has been declared and is featuring. However I would like to concatenate them in order to use the A135 as a primary key.
Any Help Please?
This quite tricky, and you would be probably better off doing manual concatenation in a select query.
But since you asked for it...
In normal usage you would have used a computed column for this, but they do not support using autoincremented columns in their declaration. So you would need to use triggers:
on insert, query information_schema.tables to retrieve the autoincremented id that is about to be assigned and use it to generate the custom id
on update, reset the custom id
Consider the following table structure:
create table workers (
id int auto_increment primary key,
name varchar(50) not null,
dept varchar(1) not null,
custom_id varchar(12)
);
Here is the trigger for insert:
delimiter //
create trigger trg_workers_insert before insert ON workers
for each row
begin
if new.custom_id is null then
select auto_increment into #nextid
from information_schema.tables
where table_name = 'workers' and table_schema = database();
set new.custom_id = CONCAT(new.dept, lpad(#nextid, 11, 0));
end if;
end
//
delimiter ;
And the trigger for update:
delimiter //
create trigger trg_workers_update before update ON workers
for each row
begin
if new.dept is not null then
set new.custom_id = CONCAT(new.dept, lpad(old.id, 11, 0));
end if;
end
//
delimiter ;
Let's run a couple of inserts for testing:
insert into workers (dept, name) values ('A', 'John');
insert into workers (dept, name) values ('B', 'Jim');
select * from workers;
| id | name | dept | custom_id |
| --- | ---- | ---- | ------------ |
| 1 | John | A | A00000000001 |
| 2 | Jim | B | B00000000002 |
And let's test the update trigger
update workers set dept = 'C' where name = 'Jim';
select * from workers;
| id | name | dept | custom_id |
| --- | ---- | ---- | ------------ |
| 1 | John | A | A00000000001 |
| 2 | Jim | C | C00000000002 |
Demo on DB Fiddle
Sorry, my answer does not fit in a comment.
I agree with #GMB.
This is a tricky situation and in some cases (selects mainly) will lead in a performance risk due you'll have to split PK in where statements, which is not recommended.
Having a column for department and another for auto_increment is more logical. And the only gap you have is to know the number of employees per department you'll have to make a count grouping by dept. Instead of a max() splitting your concatenated PK, which is is at high performance cost.
Let atomic and logic data remain in separate columns. I would suggest to create a third column with the concatenated value.
If, for some company reason, you need B1 and A1 values for employees of different departments, I'd suggest to have 3 columns
Col1 - letter(not null)
Col2 - ID(Not auto-increment, but calculated as #GMB's solution) (Not NULL)
Col3 - Concatenation of Col1 and Col2 (not null)
PK( Col1, col2)
I am trying to insert data from one table into another, and each table has an 'id' field that should be the same, but is stored different datatype. This 'id' field should represent the same unique value, allowing me to update from one to another.
In one table (the new.table one), the 'id' is stored as datatype varchar(35) and in the old.table it is datatype bigint(20) -- I believe this older table represents the integer version of the hex value stored in the new one. I am trying to update data from the new.table back into the old.table
After searching about this for a while
When I try this simple mysql update query it fails:
INSERT INTO old.table (id, field2)
SELECT CAST(CONV(id,16,10) AS UNSIGNED INTEGER), field2
FROM new.table;
It fails with this error:
Out of range value for column 'id' at row 1
I have also tried a simple
SELECT CAST(CONV(id, 16,10) AS UNSIGNED INTEGER) from new.table;
And the result is all the same integer mostly, but each hex value in new.table is unique. I've google this for two days, and could really use to help to figure out what is wrong. Thanks.
EDIT: Some of the example data from console of output of SELECT ID from new.table:
| 1d2353560110956e1b3e8610a35d903a |
| ec526762556c4f92a3ea4584a7cebfe1.11 |
| 34b8c838c18a4c5690514782b7137468.16 |
| 1233fa2813af44ca9f25bb8cac05b5b5.16 |
| 37f396d9c6e04313b153a34ab1e80304.16 |
The problem id is too high values.
MySQL will return limit-value when overflow happened.
Query 1:
select CONV('FFFFFFFFFFFFFFFF1',16,10)
Results:
| CONV('FFFFFFFFFFFFFFFF1',16,10) |
|---------------------------------|
| 18446744073709551615 |
Query 2:
select CONV('FFFFFFFFFFFFFFFF',16,10)
Results:
| CONV('FFFFFFFFFFFFFFFF',16,10) |
|--------------------------------|
| 18446744073709551615 |
I would suggest you, Implement the logic algorithm for id in your case in a function instead of use CONV function.
EDIT
I would use a variable to make new row number and insert to old table.
CREATE TABLE new(
Id varchar(35)
);
insert into new values ('1d2353560110956e1b3e8610a35d903a');
insert into new values ('ec526762556c4f92a3ea4584a7cebfe1.11');
insert into new values ('34b8c838c18a4c5690514782b7137468.16');
insert into new values ('1233fa2813af44ca9f25bb8cac05b5b5.16');
insert into new values ('37f396d9c6e04313b153a34ab1e80304.16');
CREATE TABLE old(
Id bigint(20),
val varchar(35)
);
INSERT INTO old (id, val)
SELECT rn, id
FROM (
SELECT *,(#Rn:=#Rn +1) rn
FROM new CROSS JOIN (SELECT #Rn:=0) v
) t1
Query 1:
SELECT * FROM old
Results:
| Id | val |
|----|-------------------------------------|
| 1 | 1d2353560110956e1b3e8610a35d903a |
| 2 | ec526762556c4f92a3ea4584a7cebfe1.11 |
| 3 | 34b8c838c18a4c5690514782b7137468.16 |
| 4 | 1233fa2813af44ca9f25bb8cac05b5b5.16 |
| 5 | 37f396d9c6e04313b153a34ab1e80304.16 |
The following two tables are not liked by any type of constraint.
First i have a table called subscription_plans that looks like this:
name | price | ID
-------------------
plan_A | 9.99 | 1
Plan_B | 19.99 | 2
plan_C | 29.99 | 3
I have a second table called pricing_offers. The subscription_plan_ID is a of type SET and can only contain values that match the ID's of the subscription_plans.ID (column from the above table). This table looks like this:
p_o_name | subscription_plan_ID | ID
-----------------------------------------
free donuts | 1 | 1
extra sauce | 1,2,3 | 2
pony ride | 3 | 3
bus fare -50% | 1,2,3 | 4
I'm trying to do a query to select everything (all fields *) from the first table and all names from the second table and the resulting rows should look like this:
name | price | p_o_name | ID
-------------------------------------------------------------
plan_A | 9.99 | free donuts, extra sauce, bus fare -50% | 1
Plan_B | 19.99 | extra_sauce, bus fare -50% | 2
plan_C | 29.99 | extra_sauce, pony ride, bus fare -50% | 3
The idea being that it should, for each row in the subscription_plans table, look ID field. Then go trough the second table and see what rows contain in the subscription_plan_ID, the ID of the row above. Gather those into a field caller p_o_name and insert its values to the matching response rows.
I tried doing this:
SELECT subscription_plans.*, pricing_offers.name
FROM subscription_plans INNER JOIN pricing_offers ON
FIND_IN_SET(subscription_plans.ID,subscription_plan_ID)
but i get instead of:
plan_A | 9.99 | free donuts, extra sauce, bus fare -50% | 1
this:
plan_A | 9.99 | free donuts | 1
plan_A | 9.99 | extra sauce | 1
plan_A | 9.99 | bus fare -50% | 1
Note: i get a response with all rows, but i just put the first one here to exemplify the difference.
Now, while i could do the processing in the response on my PHP page, i'm interested in knowing if i get the DB engine to output my desired result.
Do i need to create a type of constraint between the tables? If so how would i do it? I would be grateful for any help that would help me get to my proffered output result (even a better title for the question!).
If there are any unclear points, please let me know and i will clarify them.
Example of junction/intersect table usage.
create table subscription_plans
(
id int not null auto_increment primary key, -- common practice
name varchar(40) not null,
description varchar(255) not null,
price decimal(12,2) not null
-- additional indexes:
);
create table pricing_offers
(
id int not null auto_increment primary key, -- common practice
name varchar(40) not null,
description varchar(255) not null
-- additional indexes:
);
create table so_junction
( -- intersects mapping subscription_plans and pricing_offers
id int not null auto_increment primary key, -- common practice
subId int not null,
offerId int not null,
-- row cannot be inserted/updated if subId does not exist in parent table
-- the fk name is completely made up
-- parent row cannot be deleted and thus orphaning children
CONSTRAINT fk_soj_subplans
FOREIGN KEY (subId)
REFERENCES subscription_plans(id),
-- row cannot be inserted/updated if offerId does not exist in parent table
-- the fk name is completely made up
-- parent row cannot be deleted and thus orphaning children
CONSTRAINT fk_soj_priceoffer
FOREIGN KEY (offerId)
REFERENCES pricing_offers(id),
-- the below allows for only ONE combo of subId,offerId
CONSTRAINT soj_unique_ids unique (subId,offerId)
-- additional indexes:
);
insert into subscription_plans (name,description,price) values ('plan_A','description',9.99);
insert into subscription_plans (name,description,price) values ('plan_B','description',19.99);
insert into subscription_plans (name,description,price) values ('plan_C','description',29.99);
select * from subscription_plans;
insert into pricing_offers (name,description) values ('free donuts','you get free donuts, limit 3');
insert into pricing_offers (name,description) values ('extra sauce','extra sauce');
insert into pricing_offers (name,description) values ('poney ride','Free ride on Wilbur');
insert into pricing_offers (name,description) values ('bus fare -50%','domestic less 50');
select * from pricing_offers;
insert so_junction(subId,offerId) values (1,1); -- free donuts to plans
insert so_junction(subId,offerId) values (1,2),(2,2),(3,2); -- extra sauce to plans
insert so_junction(subId,offerId) values (3,3); -- wilbur
insert so_junction(subId,offerId) values (1,4),(2,4),(3,4); -- bus to plans
select * from so_junction;
-- try to add another of like above to so_junction
-- Error Code 1062: Duplicate entry
-- show joins of all
select s.*,p.*
from subscription_plans s
join so_junction so
on so.subId=s.id
join pricing_offers p
on p.id=so.offerId
order by s.name,p.name
-- show extra sauce intersects
select s.*,p.*
from subscription_plans s
join so_junction so
on so.subId=s.id
join pricing_offers p
on p.id=so.offerId
where p.name='extra sauce'
order by s.name,p.name
Basically you insert and delete from the junction table (no good really updating ever in this example).
Clean and fast joins without having to mess with slow, unwieldy sets without indexes
No one can ride the Wilbur the Poney anymore? Then
delete from so_junction
where offerId in (select id from pricing_offers where name='poney ride')
Ask if you have any questions.
And good luck!
I have this mysql table built like this:
CREATE TABLE `posts` (
`post_id` INT(10) NOT NULL AUTO_INCREMENT,
`post_user_id` INT(10) NOT NULL DEFAULT '0',
`gen_id` INT(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`post_user_id`, `post_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
When I do:
insert into posts (post_user_id) values (1);
insert into posts (post_user_id) values (1);
insert into posts (post_user_id) values (2);
insert into posts (post_user_id) values (1);
select * from posts;
I get:
post_id | post_user_id | gen_id
1 1 0
2 1 0
1 2 0
3 1 0
A unique post_id is generated for each unique user.
I need the gen_id column to be 1 2 3 4 5 6 etc. How can I increment this column when I do an insert. I tried the one below, but it won't work. What's the right way to do this?
insert into posts (post_user_id,gen_id) values (1,select max(gen_id)+1 from posts);
//Select the highest gen_id and add 1 to it.
Try this:
INSERT INTO posts (post_user_id,gen_id)
SELECT 1, MAX(gen_id)+1 FROM posts;
Use a TRIGGER on your table. This sample code can get you started:
DELIMITER //
CREATE TRIGGER ai_trigger_name AFTER INSERT ON posts
FOR EACH ROW
BEGIN
UPDATE posts
SET gen_id = (SELECT MAX(gen_id) FROM posts) + 1
WHERE post_id = LAST_INSERT_ID()
LIMIT 1;
END;//
DELIMITER ;
For my case the first number to increment was null. I resolve with
IFNULL(MAX(number), 0) + 1
or better the query became
SELECT IFNULL(MAX(number), 0) + 1 FROM mytable;
Here is the table "Autos" and the data that it contains to begin with:
AutoID | Year | Make | Model | Color |Seq
1 | 2012 | Jeep |Liberty| Black | 1
2 | 2013 | BMW | 330XI | Blue | 2
The AutoID column is an auto incrementing column so it is not necessary to include it in the insert statement.
The rest of the columns are varchars except for the Seq column which is an integer column/field.
If you want to make it so that when you insert the next row into the table and the Seq column auto increments to the # 3 you need to write your query as follows:
INSERT INTO Autos
(
Seq,
Year,
Make,
Model,
Color,
)
Values
(
(SELECT MAX(Seq) FROM Autos) + 1, --this increments the Seq column
2013,'Mercedes','S550','Black');
The reason that I put the Seq column first is to ensure that it will work correctly... it does not matter where you put it, but better safe than sorry.
The Seq column should now have a value of 3 along with the added values for the rest of that row in the database.
The way that I intended that to be displayed did not happen...so I will start from the beginning: First I created a table.
create table Cars (
AutoID int identity (1,1) Primary Key,
Year int,
Make varchar (25),
Model varchar (25),
TrimLevel varchar (30),
Color varchar (30),
CreatedDate date,
Seq int
)
Secondly I inserted some dummy values
insert into Cars values (
2013,'Ford' ,'Explorer','XLT','Brown',GETDATE(),1),
(2011,'Hyundai' ,'Sante Fe','SE','White',GETDATE(),2),
(2009,'Jeep' ,'Liberty','Jet','Blue',GETDATE(),3),
(2005,'BMW' ,'325','','Green',GETDATE(),4),
(2008,'Chevy' ,'HHR','SS','Red',GETDATE(),5);
When the insertion is complete you should have 5 rows of data.
Since the Seq column is not an auto increment column and you want to ensure that the next Seq's row of data is automatically incremented to the # 6 and its subsequent rows are incremented as well you would need to write the following code:
INSERT INTO Cars
(
Seq,
Year,
color,
Make,
Model,
TrimLevel,
CreatedDate
)
Values
(
(SELECT MAX(Seq) FROM Cars) + 1,
2013,'Black','Mercedes','A550','AMG',GETDATE());
I have run this insert statement many times using different data just to make sure that it works correctly....hopefully this helps!