Alter table add column as SELECT - mysql

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.

Related

add auto_increment to column of NULL values - MySQL

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

How to derive table value from an update in a second table (MYSQL)

I'm fairly new to MYSQL and having a tough time with triggers. I'm working with PHPmyAdmin and using InnoDB as a storage engine.
My database is meant to structure a professional sports league.
I have tables for teams and for divisions, and I want to set up the table so that a division's record can be calculated from the records of teams in that division. Here's my SQL for creating the team table:
CREATE TABLE `cs340_neffj`.`teams2` ( `teamID` VARCHAR(3) NOT
NULL ,`teamName` VARCHAR(20) NOT NULL , `teamWins` INT(3) NOT NULL ,
`teamLoss` INT(3) NOT NULL , `divID` INT(1) NOT NULL ) ENGINE = InnoDB;
And here is for the divisions table:
CREATE TABLE `cs340_neffj`.`divisions2` ( `divID` INT(1) NOT NULL ,
`divName` VARCHAR(20) NOT NULL , `divLeader` VARCHAR(20) NULL ,
`divWins` INT(3) NOT NULL , `divLoss` INT(3) NOT NULL , `leagueID` INT
(1) NOT NULL ) ENGINE = InnoDB;
So what I would like to do is, each time a row in 'teams2' is updated, sum all the wins and losses of each team in a particular division and insert it into the divWins and divLoss columns of 'divisions2'. In 'teams2', divID is a foreign key referencing 'divisions2'. Here is my attempt at a trigger.
INSERT INTO divisions2 (divWins)
SELECT SUM(teamWins)
FROM teams2
WHERE teams2.divID = divisions2.divID
I get this error when I try to update 'teams2': "#1054, unknown column 'divisions2.divID' in 'where clause'.
So why can't the database find this column? Is it because there is no value for divID?
Just assume the record already exists in table division2
You should use update instead of insert
UPDATE divisions2
SET divWins = SUM(teams2.teamWins)
FROM teams2
INNER JOIN division2 ON teams2.divID = divisions2.divID
update command will update the division2 table
details of inner join you can refer to here, which in short is select all data which match with the criteria
As my comment stated, I think these kind of data should use view instead of trigger.
For view:
CREATE VIEW view_name AS
SELECT division2.`divID`, sum(teams2.`teamWins`) as teamWins
FROM teams2
INNER JOIN division2 on teams2.divID = divisions2.divID
So every time you select the view, it will calculate the teamWins on the same time.

Best schema design to store and fetch the multiple ids in mysql

This is second time that i can face this kind of issue to retrieve the data.
CREATE TABLE `pm_projects` (
`project_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`project_name` varchar(255) NOT NULL,
`assigned_client` varchar(100) NOT NULL,
`project_detail` longtext NOT NULL,
`creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`project_status` tinyint(1) NOT NULL,
PRIMARY KEY (`project_id`),
KEY `assigned_client` (`assigned_client`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
On the above table i have a field assigned_client that holds the multiple id's of the clients that are assigned to the project with comma separated(3,4,...).
And i am trying to fetch the result on this table with the Assigned Client's Name(that is on my pm_users table) with JOIN, I tried the following:
SELECT
p.project_id, u.user_name, p.project_name,
p.creation_date, p.project_status
FROM pm_projects p
LEFT JOIN pm_users u ON u.user_id
IN (
'p.assigned_clients'
)
that returns the NULL value of u.user_name field.
Can i have to change my schema, if yes then how?
OR i am trying with wrong Query?
You can use find_in_set for this:
on find_in_set(u.user_id, p.assigned_clients) > 0;
Note that there are no single quotes around p.assigned_clients. This is another error in your query (but even if you replaced it with back quotes, the query still wouldn't work).
However, the problem is your table schema. You should have a separate association table, with one row per user and assigned client.
Trying to store this all in one field will only lead to problems, overly-complicated queries, and performance problems in the future.
I would go with a many to many link approach.
Something like
CREATE TABLE pm_project_client_link(
project_id INT,
client_id INT
)
That would allow you to write the query something like
SELECT
p.project_id,
u.user_name,
p.project_name,
p.creation_date,
p.project_status
FROM pm_projects p INNER JOIN
pm_project_client_link pcl ON p.project_id = pcl.project_id INNER JOIN
pm_users u ON pcl.client_id = user_id

Select From Where Not Exists query

Memberships table:
CREATE TABLE `Consultant_Memberships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`membership_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
Memberships_List table:
CREATE TABLE `Consultant_Memberships_List` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`consultant_id` int(11) DEFAULT NULL,
`membership_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Within the Memberships table, there is a list of 'Societies' which the member can become a part of. On selection, this is then added to the 'Memberships_List' in the form of:
id - Auto increment
consultant_id - The unique ID of the user who's added the societies
membership_id - Refers to the 'id' from the memberships table.
I want to be able to show in a drop down list only the memberships which the user hasn't chosen yet. So far I've got:
$query = $db->query("SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title` `FROM `Consultant_Memberships
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)");
I'm currently getting this error, and also unsure if this is the correct query:
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 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 'WHERE `Consultant_Memberships_List`.`id` = )' at line 1' in /Users/Sites/pages/medical.php:72
Stack trace:
#0 /Users/Sites/pages/medical.php(72): PDO->query('SELECT `Consult...')
#1 /Users/Sites/index.php(18): include('/Users/Site...')
#2 {main}
thrown in /Users/Sites/pages/medical.php on line 72
FROM is missing in the NOT EXISTS subquery.
SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title` `FROM `Consultant_Memberships
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)
you have a wrong syntax try something like this i am not writing exect query but checked in sql fiddle and thats wrond
SELECT Consultant_Memberships.id, Consultant_Memberships.title FROM Consultant_Memberships
WHERE NOT EXISTS (SELECT Consultant_Memberships.id, Consultant_Memberships.title from Consultant_Memberships
WHERE Consultant_Memberships.id = 1)
Always watch to the left from the highlighted query part. WHERE in your case
SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title`
`FROM <--- extra backtick
`Consultant_Memberships <--- unclosed backtick
by the way, do not overuse backticks. most of your fields require them not
...and you have your query totally screwed as it seems
As far as I understood your question, it have to be
SELECT cm.id, title
FROM Consultant_Memberships cm LEFT JOIN Consultant_Memberships_List
ON cm.id=membership_id WHERE membership_id IS NULL
Please note that your question has nothing to do with PDO.
it's clear SQL query question.
Kindly try this one:
SELECT a.id, a.title
FROM Consultant_Memberships a, Consultant_Memberships_List b
WHERE a.id <> b.consultant_id
The reason you are getting syntax error because if you see your subquery you will find out that you are not specifying any table in it.
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)
If you need more help, please let us know...
Regards...
Mr.777

Using mysql triggers to update fields part of a composite primary key

I'm new to mysql triggers and I'm trying to figure it out how should a trigger be created for the following case.
I have a table with the following structure:
CREATE TABLE `trigger` (
`group` int(3) NOT NULL,
`order` int(3) NOT NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`group`,`order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This is how the table would look with some sample data:
The trigger that I want to create should make sure that, for each new record added with a given group, the order field is updated with the correct order index.
So, if I were to add a new record with the group 1, the order field will be automatically be updated to the next order which, for the given example would be 4.
The following statements inside a trigger should do the trick.
DECLARE neworder INTEGER;
SELECT max(`order`) + 1 INTO neworder FROM `trigger` WHERE `group` = NEW.`group`;
SET NEW.`order` = neworder;
BTW, it's not a great idea to use reserved words for table or column names.
You might want to reconsider your naming scheme.