I have a table like this:
company_id | name
----------------------
NULL | google
NULL | amazon
All the values in company_id are NULL, and I'd like to replace those values with AUTO_INCREMENTED INT starting from 24,000. However, when I try
alter table table_name modify column company_id int AUTO_INCREMENT, add primary key;
It throws error Query 1 ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
As well as when I run
alter table `table_name` modify column `company_id` int AUTO_INCREMENT=24000, add primary key;
Any help would be appreciated!
It would be best to just add an auto increment column starting at a certain value. If you want to go the update route, then here is one option friendly for MySQL 8+:
UPDATE yourTable t1
INNER JOIN
(
SELECT name, ROW_NUMBER() OVER (ORDER BY name) rn
FROM yourTable
) t2
ON t2.name = t1.name
SET
company_id = rn + 23999
First make sure you don't have an existing PRIMARY KEY, otherwise adding a "second one" will fail.
As for your question, the syntax is incorrect, you want to do:
alter table table_name modify column company_id int PRIMARY KEY AUTO_INCREMENT;
alter table test AUTO_INCREMENT=24000,
modify column company_id int AUTO_INCREMENT,
add primary key (company_id);
fiddle
Related
I have a database with multiple tables, and I want to add a column to one table that will be populated with different strings based on the contents of another table.
Below are the tables of interest.
CREATE TABLE Locations(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Location VARCHAR(17) NOT NULL,
Is_Property BOOLEAN NOT NULL
);
CREATE TABLE Players(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Player_Name VARCHAR(17) NOT NULL,
Token VARCHAR(17) NOT NULL,
FOREIGN KEY (Token) REFERENCES Tokens(Token),
P_Location VARCHAR(17) NOT NULL,
FOREIGN KEY (P_Location) REFERENCES Locations(Location),
Bank_Balance INT NOT NULL DEFAULT 200);
ALTER TABLE Locations ADD INDEX `Location` (`Location`);
CREATE TABLE Properties AS SELECT id,Location FROM Locations
WHERE Is_Property = 1;
ALTER TABLE Properties
ADD CONSTRAINT PK_Properties PRIMARY KEY (id),
ADD COLUMN Colour VARCHAR(6),
ADD COLUMN Cost_And_Rent INT,
ADD COLUMN Owned VARCHAR(3);
CREATE TABLE Properties_Owned(
Player_id INT NOT NULL,
Prop_id INT NOT NULL,
PRIMARY KEY(Player_id, Prop_id),
FOREIGN KEY (Player_id) REFERENCES Players(id),
FOREIGN KEY (Prop_id) REFERENCES Properties(id));
The Properties and Properties_Owned tables are of interest in this case. I want to create a column called Owned in Properties and populate it with "Yes" or "No" based on if the primary key appears under Prop_id in Properties_Owned. Ergo if it does, Properties.Owned will show "Yes", and if not, "No".
I've tried using the CASE function, but I'm unsure of if it can be used without calling a SELECT query. Below is my last attempt to do so, but the syntax is wrong somewhere or just misguided altogether.
CASE
WHEN id IS IN properties_owned.Prop_id THEN Properties.Owned = "Yes"
ELSE "No" ;
It generates the error code:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN id IS IN properties_owned.Prop_id THEN Properties.Owned = "Yes" ELSE ' at line 1
Edit: As there was a request for sample data, here it is:
INSERT INTO Locations(Location,Is_Property) VALUES ("GO", 0),
("London", 1),
("Paris", 0),
("China", 1),
("New Zealand", 0),
("Sydney", 1),;
INSERT INTO Players(Player_Name,Token,P_Location,Bank_Balance) VALUES
("Mary","Battleship","London",190),
("Bill","Dog","Paris",500),
("Jane","Car","China",150),
("Norman","Thimble","London",250);
INSERT INTO Properties_Owned(Player_id,Prop_id) VALUES
(1,1),
(2,2),
(3,3),
(4,4),
(4,5);
Thus the Properties_Owned table will look like this:
Player_id | Prop_id
----------|---------
1 |1
2 |2
3 |3
4 |4
4 |5
And so in the Properties table under Owned, if Properties.id appears in Prop_id above, the Owned column should yield "Yes".
The table Properties_Owned reflects an (n:n)-relation (many-to-many). But according to your comment, a property cannot be owned by multiple players at the same time. And that would be an (n:1)-relation (many-to-one). In that case you do not need the Properties_Owned table and can just add a column Player_id (or owned_by_player_id) to the Properties table as foreign key referencing the Players table.
alter table Properties
add column Player_id int default null,
add foreign key (Player_id) references Players(id);
Then the information required for the Owned column will be already in the same table. You just need to "manipulate" it in your SELECT statements. For example with:
select
p.*,
case when Player_id is null then 'No' else 'Yes' end as Owned
from Properties p;
No need to store the same information redundantly. That would "bite" you sooner or later. Avoid redundancy when possible.
If your MySQL version (5.7+ required) supports Generated Columns you can also let the database maintain the redundancy.
alter table Properties
drop column Owned,
add column Owned varchar(3)
as (case when Player_id is null then 'No' else 'Yes' end) virtual;
Now the (genrated) column is dependent on Player_id column and you don't need (and cannot) store anything there but can select it. virtual means that it is not stored but generated (on the fly) when it's needed. Now you can read it in your queries as if it is normal column.
See example on db-fiddle.com
And again: Avoid redundant data when possible. At least use foreign keys to avoid data inconsistency.
You could create a view that extends your table by the column you want. There you can use a CASE statement.
CASE WHEN id IN SELECT Prop_id FROM properties_owned THEN 'Yes' ELSE 'No'
If this is not what you want, you could possibly use triggers on both tables that fill/update the column on on create/on delete
Initially you could fill the column with something like this:
UPDATE Prop_id SET properties_owned = CASE WHEN id IN SELECT Prop_id FROM properties_owned THEN 'Yes' ELSE 'No' WHERE
So I wanted to add new column to my table made from a select using two other tables. I tried a query like this:
ALTER TABLE order ADD cost DECIMAL(5,2) AS (SELECT SUM(price*pieces) FROM book JOIN details ON id_book=book_id GROUP BY order_id);
And I get error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select sum(price*pieces) from book join details on id_book=book_id group by order_id ' at line 1
My other tables look like this:
CREATE TABLE details (
id_d INT(10) NOT NULL AUTO_INCREMENT,
book_id INT(10) DEFAULT NULL,
order_id INT(10) DEFAULT NULL,
pieces INT(10) DEFAULT NULL
...
CREATE TABLE book (
id_book INT(10) NOT NULL AUTO_INCREMENT,
price DECIMAL(5,2) DEFAULT NULL,
...
This
SELECT SUM(price*pieces) FROM book JOIN details ON id_book=book_id GROUP BY order_id; works but I really don't know how to add this as a new column :(
You can't specify the data to fill the column in the ALTER TABLE statement. That needs to be done in a separate UPDATE statement.
ALTER TABLE order ADD cost DECIMAL(5,2) DEFAULT 0;
UPDATE order AS o
JOIN (
SELECT d.order_id, SUM(d.pieces, * b.price) AS cost
FROM details AS d
JOIN book AS b ON d.book_id = b.id_book
GROUP BY d.order_id) AS d ON d.order_id = o.order_id
SET o.cost = d.cost
Question's been posted for some time now and the funny thing is I also thought syntax was a bit odd when I saw it in my project and I ended up here looking for some explanation. I understand now that while it may not be possible to use both ALTER TABLE and a fill-in value statement, one can declare a column field as a 'COMPUTED' type meaning you can declare a function that will execute on the fly in every select statement, I leave here a sample code reference using this syntax for whoever finds it useful:
ALTER TABLE ACCOUNTS ADD ACCOUNT_CASH AS get_VALUE ('CASH', CURRENCY, BUSINESS_TYPE, STATUS );
Though in most of the cases, a trigger would be a better approach.
My Query:
INSERT INTO `test` (`name`)
SELECT DISTINCT c4
FROM `imp_asset` WHERE c4 !='' ORDER BY c4 ASC;
Error Code: 1062
Duplicate entry '0' for key 'PRIMARY'
My Test table:
Field Type
id int(11) NOT NULL
name varchar(200) NULL
Try to make your table as:
mysql> CREATE TABLE test(
id int(11) NOT NULL,
name varchar(200) NULL,
PRIMARY KEY (id))
or if the table is already created then try to alter it using the ALTER statement.
alter table test modify column id INT auto_increment;
The problem is that ID is of type INT and is a primary key, but on your insert query you are not specifying any value for ID and there's no default value defined.
You have to make your ID column as an auto_increment:
alter table test modify column id int auto_increment;
Please see an example fiddle here.
Good day everyone. Hope someone can helps me in my experiments.
I have a simple Table for my needs and it's even have some data inside.
CREATE TABLE IF NOT exists main.test (
ID INT(11) NOT NULL,
NAME varchar(30) NOT NULL,
DATE_CREATED timestamp NOT NULL,
PRIMARY KEY (ID));
But then I should update this table with adding column FK_.
How can I check if table had already has field FK_?
If such column is not exist do:
ALTER TABLE main.test
ADD COLUMN FK INT(11),
ADD FOREIGN KEY (FK)
REFERENCES test2(ID_test2)
As I use java decision of my problem was using ResultSet.
ResultSet set = statement.executeQuery(query);
set.next();
int result = set.getInt(1); //it always return only one row
set.close();
And this is my sql-query:
SELECT COUNT(COLUMN_NAME) FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'main'
AND TABLE_NAME = 'test'
AND COLUMN_NAME = 'FK";
When I'll get a result I can decide what query I should to use.
I am converting our project database from SQL Server to MySQL, the DB conversion has done already.
We have code as below to identify duplicate records based on hashcode and update them as duplicate.
Rank function in MySQL ([Rank function in MySQL) need rank based on age which will start with 1 and increment by 1 for each record. But for me Rank for each hascode should start from 1 and increment by 1 for same hascode, if new hascode comes Rank should start from 1.
update table set Duplicate=1
WHERE id IN
( SELECT id FROM (
select RANK() OVER (PARTITION BY Hashcode ORDER BY Date asc) R,*
from table )A where R!=1 )
Below is table structure
CREATE TABLE TBL (
id int(11) NOT NULL AUTO_INCREMENT,
FileName varchar(100) DEFAULT NULL,
date datetime DEFAULT NULL,
hashcode varchar(255) DEFAULT NULL,
FileSize varchar(25) DEFAULT NULL,
IsDuplicate bit(1) DEFAULT NULL,
IsActive bit(1) DEFAULT NULL
PRIMARY KEY (`id`)
)
Please help me to migrate this code to MYSQL.
You don't need to use enumeration for this logic. You just want to set the duplicate flag on everything that is not the minimum date for the hashcode:
update table t join
(select hashcode, min(date) as mindate
from table t
group by hashcode
) tt
on t.hashcode = tt.hashcode and t.date > tt.mindate
set t.Duplicate = 1;
MySQL features a rather unique way to delete duplicates:
alter ignore table YourTable
add unique index ux_yourtable_hashcode (hashcode);
The trick here is in the ignore option:
If IGNORE is specified, only one row is used of rows with duplicates
on a unique key. The other conflicting rows are deleted.
But there are also other ways. Based on your comment, there is an auto_increment column called id. Since this column is unique and not null, you can use it to distinguish duplicates. You'd need a temporary table to work around the cant specify target table TBL for update in FROM clause error:
create temporary table tmp_originals (id int);
insert tmp_originals
(id)
select min(id)
from YourTable
group by
hashcode;
update YourTable
set Duplicate = 1
where id not in (select id from tmp_originals);
The group by query selects the lowest id per group of rows with the same hashcode.