Update a table in MySQL with all data from another table - mysql

I have 3 tables: ak_class, ak_objects, ak_class_object
ak_class:
class_id | class_description | class_name |
1 | some description | some name |
2 | some description | some name |
3 | some description | some name |
ak_objects:
object_id | object_description | object_name |
1 | some description | some name |
2 | some description | some name |
3 | some description | some name |
ak_class_object:
class_object_id | class_id | object_id |
1 | 1 | 1 |
2 | 2 | 2 |
3 | 3 | 3 |
I need to fill in the ak_class_object with a class_id from ak_class table and object_id from ak_objects table.
The question is how can I update (I need to update as there is some wrong data currently) the class_id from the ak_class table with all the ids? I was thinking of using it with JOIN ut I don't know which id to use to Join them as class_id is only to be updated
UPD: I was trying to do it like this, but it didn't work:
DELIMITER $$
DROP PROCEDURE class_object_1$$
CREATE PROCEDURE class_object_1()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE (i < 250000) DO
UPDATE ak_class_object
SET class_id = SELECT DISTINCT class_id from ak_class, object_id = SELECT DISTINCT class_id from ak_objects;
SET i = i + 1;
END WHILE;
END$$

I am writing the generic syntax, change the table names and column name as per your requirements.
update table1 inner join table2
on table1.id = table2.fk_id
set table1.column = table1.columnUpdated

Related

How can I update a column between two unique values in another column in MySQL?

How can I update a column between two unique values in another column in MySQL or MariaDB?
Consider a table called Example that has three columns:
Id: An auto-increment integer ID
RandomId: A series of random and unique GUIDs
IsUpdated: A column currently only containing NULL values, that needs to be updated
* ----------------------------------------------------- *
| Id | RandomId | IsUpdated |
| ----------------------------------------------------- |
| 1 | c446980b-cf2f-4f2d-a27b-28d6bde6415d | NULL |
| 2 | d6a1a52c-d073-4019-836a-67cf6551d958 | NULL |
| 3 | 7a339a6a-8e57-4373-84fd-1b40ee51c884 | NULL |
| 4 | 56b908a7-fb07-4f4c-a25d-699cf40cf690 | NULL |
| 5 | fac75ce6-a605-453a-958c-74f197e20a11 | NULL |
* ----------------------------------------------------- *
I would like to update IsUpdated between two specific GUIDs, like so:
UPDATE Example
SET IsUpdated = 1
WHERE RandomId >= 'd6a1a52c-d073-4019-836a-67cf6551d958' -- Starting Here
AND RandomId <= '56b908a7-fb07-4f4c-a25d-699cf40cf690' -- Ending Here
The resulting table should look like the following:
* ----------------------------------------------------- *
| Id | RandomId | IsUpdated |
| ----------------------------------------------------- |
| 1 | c446980b-cf2f-4f2d-a27b-28d6bde6415d | NULL |
| 2 | d6a1a52c-d073-4019-836a-67cf6551d958 | 1 |
| 3 | 7a339a6a-8e57-4373-84fd-1b40ee51c884 | 1 |
| 4 | 56b908a7-fb07-4f4c-a25d-699cf40cf690 | 1 |
| 5 | fac75ce6-a605-453a-958c-74f197e20a11 | NULL |
* ----------------------------------------------------- *
But since the Ids are not sequential, this method does not appear to work.
What would be the most efficient way to update a column (IsUpdated) between two unique values in another column (RandomId)?
You need to filter by id instead. I would recommend the update ... join syntax:
update example e
inner join (
select min(Id) minId, max(Id) maxId
from example
where RandomId in (
'd6a1a52c-d073-4019-836a-67cf6551d958',
'56b908a7-fb07-4f4c-a25d-699cf40cf690'
)
) i on e.id between i.minId and i.maxId
set e.IsUpdated = 1
Note that this does not stricly guarantee that guid are matched on the first and last rows (it would also work the other way around). You can be more specific with two joins:
update example e
inner join (
select Id
from example
where RandomId = 'd6a1a52c-d073-4019-836a-67cf6551d958'
) eMin on e.id >= eMin.id
inner join (
select Id
from example
where RandomId = '56b908a7-fb07-4f4c-a25d-699cf40cf690'
) eMax on e.id <= eMax.id
set e.IsUpdated = 1

update the link table

I'm validating following SQL approach from the community where I'm completely updating the user's roles. (Full update of the join table)
User
+----+-------+------+
| id | first | last |
+----+-------+------+
| 1 | John | Doe |
| 2 | Jane | Doe |
+----+-------+------+
Role
+----+----------+
| id | name |
+----+----------+
| 1 | admin |
| 2 | accounts |
| 3 | sales |
+----+----------+
UserRole
+--------+--------+
| userid | roleid |
+--------+--------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 2 | 3 |
+--------+--------+
My SQL approach -> first delete all, second insert all records
DELETE FROM UserRole WHERE userid = 1;
INSERT INTO UserRole(userid, roleid) VALUES(1, 2), (1, 3);
Is there a better way? I mean to do this in a single query possibly for these sorts of linking/join tables?
Edit
I think what I should have said to find an efficient SQL operation instead of a single query.
Here's another SQL
DELETE FROM UserRole WHERE user_id = 1 AND role_id NOT IN (2, 3);
INSERT INTO UserRole(user_id, role_id) VALUES(1, 2), (1, 3)
ON DUPLICATE KEY UPDATE user_id = VALUES(user_id), role_id = VALUES(role_id);
If you want to add all roles for all users into the userRoles table, you can delete from userRoles, then recreate table like below:
DECLARE #users TABLE ( userID INT, UserName NVARCHAR(MAX) )
DECLARE #roles TABLE ( roleID INT, RoleName NVARCHAR(MAX) )
DECLARE #userRoles TABLE ( userID INT, roleID INT )
INSERT INTO #users (userID,UserName) VALUES (1,'name1'),(2,'name2'),(3,'name3')
INSERT INTO #roles (roleID,RoleName) VALUES (1,'admin'),(2,'accounts'),(3,'sales')
INSERT INTO #userRoles (userID,roleID)
SELECT U.userID,R.roleID FROM #users U
FULL OUTER JOIN #roles R ON 1=1
ORDER BY userID
SELECT * FROM #userRoles
OUTPUT:
userID roleID
1 1
2 1
3 1
1 2
2 2
3 2
1 3
2 3
3 3

Join 2 tables and create a new row showing if table 2 exists in table 1

I have this two tables
Table 1
+-----------+----------+
| support_id| Name |
+-----------+----------+
| 1 | Name 1 |
| 2 | Name 2 |
+-----------+----------+
Table 2
+-----------+----------+
| school_id | support_id|
+-----------+----------+
| 2314 | 1 |
+-----------+----------+
Desire output
+-----------+----------+------------+
| school_id |support_id| has |
+-----------+----------+------------+
| 2314 | 1 | Yes |
| 2314 | 2 | No |
+-----------+----------+------------+
How can I add the third row telling me if table 2 is in table 1?
Thanks in advance!
What do you mean a table1 "is" in table2?
The field support_id is the same as the support_id in table 2?
Or the field or the school_id is the same?
You need a field to be the same in both tables in order to make a connection (Foreign Key), make a join and connect both tables.
Considering support_id to be the foreigh key (the value shared between both tables) you can use this select:
SELECT school_id, IF(support_id is not null, "Yes", "No") as Has
FROM table1 LEFT JOIN table2
ON table1.support_id = table2.support_id;
I'd use a left join and then a case expression to format the results:
SELECT t2.*, CASE WHEN t1.support_id IS NOT NULL THEN 'Yes' ELSE 'No' END
FROM t2
LEFT JOIN t1 ON t2.support_id = t1.support_id

Delete duplication based on info of one column

I would like to eliminate duplication based on company id.
I dont care which of the records under the model name will be deleted / stay.
I have this results:
+------------+------------------+
| company id | model name |
+------------+------------------+
| 1 | chevrolet camaro |
| 1 | chevrolet spark |
| 1 | chevrolet cruze |
| 2 | mercedes c class |
| 2 | mercedes E class |
+------------+------------------+
And I would like to get these results:
+------------+------------------+
| company id | model name |
+------------+------------------+
| 1 | chevrolet camaro |
| 2 | mercedes c class |
+------------+------------------+
Or these results(The point is I don't care which of the model name will be eliminated):
+------------+------------------+
| company id | model name |
+------------+------------------+
| 1 | chevrolet spark |
| 2 | mercedes E class |
+------------+------------------+
What should I do?
You can use a group by:
select companyid, min(modelname) as modelname
from t
group b companyid;
Try this
ALTER IGNORE TABLE 'yourTableName' ADD UNIQUE ('company id');
reference : here
I would try this approach:
declare #tbl table (ID int, car nvarchar(100))
declare #tblTemp table (ID int, car nvarchar(100))
insert into #tbl(ID, car)
values
( 1 ,'chevrolet camaro'),
(1 ,'chevrolet spark'),
(1 ,'chevrolet cruze'),
(2 ,'mercedes c class'),
(2 ,'mercedes E class'),
(1 ,'chevrolet camaro'),
(1 ,'chevrolet spark'),
(1 ,'chevrolet cruze'),
(2 ,'mercedes c class'),
(2 ,'mercedes E class')
insert into #tblTemp
select distinct MAX(id), car from #tbl
group by car
delete from #tbl
insert into #tbl (car)
select car from #tblTemp
declare #i int
SELECT #i= ISNULL(MAX(id),0) FROM #tbl
update #tbl
set id = #i , #i = #i + 1
where id is null
select * from #tbl
SQL result:

Limit data from another table attribule

I have table Job and table Company. Each job item will be for a company. I would like to write a query that will list the jobs.
Company has a quantity column. When jobs are listed from Job, the number of jobs listed for a given company is the number in this Quantity column.
Data example
For example: Company A has quantity = 2. The query data will return the top 2 jobs.
How can I do this in a sql query?
Table Job
| id | Title | Company ID |
|:---|------:|:------------:|
| 1 | Job 1 | 1
| 2 | Job 2 | 1
| 3 | Job 3 | 1
| 4 | Job 4 | 2
| 5 | Job 5 | 2
Table Company
| id | Title | Quantity|
|:---|----------:|:-------:|
| 1 | Company 1| 2
| 2 | Company 2| 2
And the result of query Select * From Job => With condition limit quantity of company.
| id | Title | Company ID |
|:---|------:|:----------:|
| 1 | Job 1 | 1
| 2 | Job 2 | 1
| 4 | Job 4 | 2
| 5 | Job 5 | 2
Create procedure and you can use variable with LIMIT
DELIMITER $$
CREATE PROCEDURE `GetJobs`()
NO SQL
BEGIN
DECLARE cid INT;
DECLARE jobsLimit INT;
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
CREATE TEMPORARY TABLE JobListTemp (
id INT,
Title VARCHAR(255),
CompanyID INT
) ENGINE=MEMORY;
SELECT COUNT(*) FROM Company INTO n;
SET i=0;
WHILE i<n DO
SET cId = (SELECT id FROM Company LIMIT i,1);
SET jobsLimit = (SELECT quantity FROM Company WHERE id = cId LIMIT 1);
INSERT INTO JobListTemp SELECT * FROM Job WHERE CompanyID = cId LIMIT jobsLimit;
SET i = i + 1;
END WHILE;
SELECT * FROM JobListTemp;
DROP TABLE JobListTemp;
END$$
DELIMITER ;
I think you can use the inner sqlquery.
For example:
select innerTab.id,innerTab.Title,innerTab.companyid
from (select * from job order by id limit 2) innerTab
inner join Company on innerTab.companyid=company.companyid
The colname is not same with you.
So you can change it to make sure the sql can run.