How to Join two tables with same attributes? - mysql

I have two tables, I want to create a new table with same attribute using the data from two tables.
following is the code im trying
/* Create a table called NAMES */
CREATE TABLE NAMES(Id integer PRIMARY KEY, Name varchar(100));
CREATE TABLE GAMES(Id integer PRIMARY KEY, Name varchar(100));
CREATE TABLE JJ(Id integer PRIMARY KEY, Name varchar(100));
/* Create few records in this table */
INSERT INTO NAMES VALUES(1,'Tom');
INSERT INTO NAMES VALUES(2,'Lucy');
INSERT INTO NAMES VALUES(3,'Frank');
INSERT INTO NAMES VALUES(4,'Jane');
INSERT INTO NAMES VALUES(5,'Robert');
INSERT INTO GAMES VALUES(7,'Football');
INSERT INTO GAMES VALUES(6,'Rugby');
COMMIT;
/* Display all the records from the table */
SELECT * FROM NAMES;
SELECT * FROM GAMES;
INSERT INTO JJ (Id, Name) VALUES((SELECT * FROM NAMES), (SELECT * FROM GAMES));
SELECT * FROM JJ; 'Error: near line 21: sub-select returns 2 columns - expected 1'

this will work for oracle :
INSERT INTO JJ (Id, Name)((SELECT * FROM NAMES) union all(SELECT * FROM GAMES));
for mysql :
insert into JJ select * from Names union all select * from Games;
but as Zaynul said when two primary key matches it will throw an error!!!!

the way you trying to merge two table is not better aproach b/c two different table primary key may same which will thrown error in times of 3rd table insertion(duplicate key). i would prefer change your table structure make all three table primary key auto increment and push just name not id
INSERT INTO JJ ( Name)
select name from (
SELECT name FROM NAMES
union all
SELECT name FROM GAMES
) t

I would suggest declaring JJ as:
CREATE TABLE JJ (
Id integer auto_increment PRIMARY KEY,
Name varchar(100)
);
insert into jj (name)
select name from names union all
select game from games;

Related

insert a new record into a mysql table with one of the values incremented by 1

I've got the following table:
productId price
1 price_value1
2 price_value2
3 price_value3
I would like to insert a new product into the table and assign it a new productId. In this case its value equals to 4.
So I want my new table to look like so:
productId price
1 price_value1
2 price_value2
3 price_value3
4 price_value4
So as far as I understand, in order to do that I have to somehow retrieve the max value of productId and insert it using INSERT INTO mytable VALUES (productId + 1, price_value4).
But how do I find out the maximum value of productId?
I tried INSERT INTO mytable VALUES (SELECT MAX(productId) + 1 FROM mytable, price_value4) but it didn't work.
This should Work:
Select the max(productID) and price_value4 as a columns from mytable and insert the result.
INSERT INTO mytable (SELECT MAX(productId) + 1, 'price_value4' FROM mytable);
However, if you are not going to jump some number you can just add an auto increment id key to product_id and then you will have only to insert the price, the product ID will be incremented automatically..
This will do so :
ALTER TABLE mytable
MODIFY COLUMN `productId` INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT;
you can change INT(10) with the INT(5) for example depanding on the size you want to give to your productId column
EDIT :
In return to the OP question in comments why his solution wouldn't work
Some suggetions says you have to make the SELECT statment in insert always between parenthesis
INSERT INTO mytable VALUES ( (SELECT MAX(ID)+1 FROM mytable) , price_value4)
.. In my Case it Return
(1093): You can't specify target table
'mytable' for update in FROM clause
AND HERE IS WHY (Quoting From the documentation)
When selecting from and inserting into the same table, MySQL creates
an internal temporary table to hold the rows from the SELECT and then
inserts those rows into the target table. However, you cannot use
INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table,
because TEMPORARY tables cannot be referred to twice in the same
statement
BUT there is away to overcome by using a query instead of the table itself in the FROM, which has the effect of copying the requested table values instead of referencing the one that you are updating..
INSERT INTO mytable VALUES (
(SELECT MAX(ID)+1 FROM (SELECT * FROM mytable ) as mytmp ),
'price_value4');
OR (Quoting From the documentation)
To avoid ambiguous column reference problems when the SELECT and the
INSERT refer to the same table, provide a unique alias for each table
used in the SELECT part, and qualify column names in that part with
the appropriate alias.
INSERT INTO mytable Values ( (SELECT MAX(ID)+1 FROM mytable as mytmp) , 'price_value4')
This is a duplicate question. In order to take advantage of the auto-incrementing capability of the column, do not supply a value for that column when inserting rows.
A simple syntax to create table
CREATE TABLE Product (
productId MEDIUMINT NOT NULL AUTO_INCREMENT,
price INT NOT NULL,
PRIMARY KEY (productid)
);
While inserting supplied default or leave column as blank or supplied value as NULL. Take a look at below code snippet.
INSERT INTO Product (price) VALUES
('10'),('20'),('4'),
('30');
refer this link

How to insert if not exists with selecting from same table?

I have my table schema in H2 db as follows:
create table if not exists Test ( id bigint not null,name varchar(255), primary key (id) );
alter table Test add constraint if not exists Test_NAME UNIQUE (name);
I want to insert a value for the name attribute as 'Default' if it does not exist in the table by selecting the latest id value from the table and increment it by one.
Example:
Do not insert if an entry for name = Default already exists.
ID | Name
1 | Default
Insert if an entry for name = Default does not exists.
ID | Name
1 | ABC
2 | XYZ
For the id column, find the max id and increment it by one. In this case, insert id=3 and name=Default.
My query is as follows:
INSERT INTO Test (id , name)
SELECT max(id) + 1, 'Default' from Test
WHERE NOT EXISTS (SELECT * FROM Test where name='Default');
However, it gives me an error saying:
NULL not allowed for column "ID"; SQL statement
as it applies the where condition on the inner select statement.
I also tried:
MERGE INTO Test KEY(name) VALUES (SELECT MAX(id) + 1 from Test, 'Default');
It gives an error because, merge tries to update with the new values.
If it finds 'Default', it will update the row with new id causing primary key violation.
Is there a better way to do this? How can I make the query work?
You are massively overcomplicating this. Define the id field as auto increment and place a unique index on the name field. The unique index prevents duplicate names to be inserted, while the auto increment increases the value of the id field by 1 (by default) if the insert is successful.
I updated id to auto increment and the following query work flawlessly
INSERT INTO Test (name) select * from (select 'Default') as tmp WHERE NOT EXISTS (SELECT name from Test where name='Default');
when you run your query first time, no record found in table so, it give error 'null' there, so if you add IFNULL() function there as below
INSERT INTO Test (id , name)
SELECT **IFNULL**(max(id),0) + 1, 'Default'
FROM Test
WHERE NOT EXISTS (SELECT * FROM Test where name='Default');

Insert into Table by getting NextVal of Sequence in PostgreSQL

I have a table called SEQ_TABLE which has two columns, SEQ_NAME and ID
SEQ_NAME | ID
----------------------
SEQ_TABLE_10 | 1
SEQ_TABLE_20 | 5
Where ID is the Max of COLUMN_1 of TABLE_10 and TABLE_20
Now, I have to Insert new records into TABLE_10 by obtaining nextvalue of sequence from SEQ_TABLE.
I have written PostgreSQL query as follows:
INSERT INTO TABLE_10 (COLUMN_1, COLUMN_2, COLUMN_3) VALUES ((SELECT nextval(SEQ_TABLE)), 'Bangalore' ,NULL);
When I execute above Query, It is giving below error:
********** Error **********
ERROR: column "SEQ_TABLE_10" does not exist
SQL state: 42703
Character: 99
But, following Query works fine in MySQL Database:
INSERT INTO TABLE_TABLE(COLUMN_1, COLUMN_2, COLUMN_3) VALUES ((SELECT nextval('TABLE_172_SEQ','true')), 'Bangalore' ,NULL);
What is the Exact Postgres Query to achieve it in PostgreSQL DB?
You want to create a sequence, not a table(SEQ_TABLE)
Kindly refer this link
https://www.postgresql.org/docs/8.1/static/sql-createsequence.html
Eg.
CREATE SEQUENCE serial START 101;
SELECT nextval('serial');
create table MyTable(col1 int,col2 varchar(20));
INSERT INTO MyTable VALUES (nextval('serial'), 'nothing');
In current PostgreSQL versions you would use identity columns:
CREATE TABLE table_10 (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
other text NOT NULL
);
That will implicitly generate a sequence. You are not allowed to insert numbers into into id, but you have to
INSERT INTO table_10 (other) VALUES ('new');
or
INSERT INTO table_10 (id, other) VALUES (DEFAULT, 'new');
and id is automatically filled with the next value from the sequence.
On older PostgreSQL versions, you would use serial or bigserial:
CREATE TABLE table_10 (id serial PRIMARY KEY, other text NOT NULL);
Then id is of type integer, a sequence table_10_id_seq is created and a nextval call is added to the DEFAULT clause of the id column.
You can examine this with \d in psql:
\d table_10
Table "laurenz.table_10"
Column | Type | Modifiers
--------+---------+-------------------------------------------------------
id | integer | not null default nextval('table_10_id_seq'::regclass)
other | text | not null
Indexes:
"table_10_pkey" PRIMARY KEY, btree (id)
Moreover, the sequence belongs to the table and will be dropped automatically when the table is dropped.
You insert rows omitting the id column like this:
INSERT INTO table_10 (other) VALUES ('something');
Then the DEFAULT values will be used.
If you want to do the same thing “on foot”, for example to use a different name or different starting values for the sequence, that would work like this:
CREATE TABLE table_10 (id integer PRIMARY KEY, other text NOT NULL);
CREATE SEQUENCE table_10_id_seq OWNED BY table_10.id;
ALTER TABLE table_10 ALTER id SET DEFAULT nextval('table_10_id_seq');

Copy row from one table to another with a additional primary key

I tried this:
INSERT INTO event_log_tracker_table
SELECT * FROM event_tracker_table WHERE eventid = '560'
However I get this error:
Error Code: 1136. Column count doesn't match value count at row 1
The columns match exactly the same except for one thing...
I added one more column (eventlogid) in event_log_tracker_table to be a primary key. How can I insert a row, from another table and have it add to a primary key in the new table?
Below is a structure of the tables.
event_log_tracker_table (24 columns)
-----------------------
eventlogid - PK
eventid - INT
//
// 22 other columns
//
event_tracker_table (23 columns)
-----------------------
eventid - PK
//
// 22 other columns
//
I have tried to do this:
INSERT INTO event_log_tracker_table
SELECT null, * FROM event_tracker_table WHERE eventid = '560'
As documented under SELECT Syntax:
Use of an unqualified * with other items in the select list may produce a parse error. To avoid this problem, use a qualified tbl_name.* reference
SELECT AVG(score), t1.* FROM t1 ...
Therefore, instead of SELECT NULL, * you could should qualify the wildcard:
INSERT INTO event_log_tracker_table
SELECT NULL, event_tracker_table.*
FROM event_tracker_table
WHERE eventid = '560'

Output current id of inserted record using OUTPUT in a trigger

I need to do this: On inserted record I need to store Inserted item identity and selected item identity. (Example below)
I'm using after insert trigger (basically I copy one row from one table into another and do some more modifications.
I have a table parameter like this:
DECLARE #Tempequipment TABLE
(Equipment_Id int,
DefaultEquipment_Id INT)
Then I insert into table like this:
INSERT INTO dbo.tblEquipmentType
( Name, EquipmentType_Id)
SELECT name,(SELECT Equiment_Id FROM INSERTED)
FROM dbo.tblDefaultEquipmentType
This works fine!
What I need to do is: I need to insert into #TempEquipment EquipmentTypeId's that were just ineserted (can be more than one) and DefaultEquipmentTypeId's that were just copied.
I was thinking about doing something like:
INSERT INTO dbo.tblEquipmentType
( Name, EquipmentType_Id)
Output EquipmentTypeId, DefaultEquipmentTypeId into #TempEquipment
SELECT name,(SELECT Equipment_Id FROM INSERTED)
FROM dbo.tblDefaultEquipmentType
but of course this is not going to work, since it cannot get values from select statement, and not written correctly.
Any help is appreciated!
UPDATE:
I have an Item. Item can be built on different equipment. Equipment has types (foreign key. And equipmentType has attributes (foreignkey).
So this mean that we have four tables Item->Equipment->EquipmentType->EquipmentAttribute.
I need to store default EquipmentTypes and default EquipmentAtrributes for that type.
So I also got these replationship: Equipment->DefaultEquipmentType->DefaultEquipmentAttribute.
Now, When I insert new Item and select an equipment I want to copy defaults over to real tables (EquipmentType, EquipmentAttribute).
Is it clear at least a little?
Aside from how you're trying to do this (which isn't working), what specifically are you trying to do?
It may be that this can be resolved by changing / normalizing your paradigm, instead of some kind of exotic code. For example, it looks odd to have a customers table with an orderID field in it. Unless your customers only ever order one thing... I would have expected to see a customers table, an items table, and then an orders table that joined customers with items.
Hope that makes sense -- but anyway, if not, can you post your table structure, and maybe be a little more clear on what you know ahead of time (e.g., I imagine you know who your customers are, and what they ordered...before you do the insert...yes?)
For an INSERT statement you can only access the columns which are in the insert column list, so the solution is to rewrite the statement as a MERGE statement which can access all the columns including columns which are in the INSERT target table for instance IDENTITY columns.
In the demo I've used dbo.INSERTED to emulate the virtual table INSERTED from the trigger.
USE master
GO
IF DB_ID('MergeOutputExample') IS NOT NULL
DROP DATABASE MergeOutputExample
GO
CREATE DATABASE MergeOutputExample
GO
USE MergeOutputExample
GO
DECLARE #Tempequipment TABLE
(EquipmentId int,
DefaultEquipmentId INT,
ID int);
CREATE TABLE dbo.INSERTED
(
EquipmentTypeId int PRIMARY KEY
);
CREATE TABLE dbo.tblEquipmentType
(
ID int IDENTITY(1,1),
Name varchar(50),
EquipmentTypeId int PRIMARY KEY
);
CREATE TABLE dbo.tblDefaultEquipmentType
(
EquipmentTypeId int,
DefaultEquipmentTypeId int IDENTITY(1,1) PRIMARY KEY,
Name varchar(50)
);
INSERT dbo.inserted
(
EquipmentTypeId
)
VALUES (1);
INSERT dbo.tblDefaultEquipmentType
(
EquipmentTypeId,
Name
)
VALUES (
1,
'Hammer'
);
MERGE dbo.tblEquipmentType AS ET
USING (
SELECT DE.EquipmentTypeId,
DE.DefaultEquipmentTypeId,
DE.Name
FROM dbo.tblDefaultEquipmentType DE
INNER JOIN dbo.INSERTED I
ON DE.EquipmentTypeId = I.EquipmentTypeId
) AS DET
ON ET.EquipmentTypeId = DET.EquipmentTypeId
WHEN NOT MATCHED BY TARGET
THEN INSERT
(
Name,
EquipmentTypeID
)
VALUES
(
DET.Name,
DET.EquipmentTypeID
)
OUTPUT DET.EquipmentTypeId,
DET.DefaultEquipmentTypeId,
INSERTED.ID
INTO #Tempequipment;
SELECT *
FROM #Tempequipment;
SELECT *
FROM dbo.tblEquipmentType;