MySQL create / select adds fields from the source table - mysql

I encountered an issue with MySQL, adding fields from the selected source table.
Here is an example (you can find it on SQL Fiddle :
CREATE TABLE source_table (
id INT UNSIGNED NOT NULL,
foo VARCHAR(3),
INDEX (id)
);
INSERT INTO source_table (id, foo) VALUES (1, "one");
// Create another table and fill it from the source_table
CREATE TABLE example_table (
id INT UNSIGNED NOT NULL,
bar VARCHAR (3),
INDEX (id)
) SELECT
source_table.id,
source_table.foo
FROM source_table
WHERE source_table.id = 1;
In the end, my example_table will have a foo field, that I never requested to be create.
Plus, bar will be empty while foo will be filled.
The solution I found is to use aliases for each field, but it's redundant:
CREATE TABLE example_table (
id INT UNSIGNED NOT NULL,
bar VARCHAR (3),
INDEX (id)
) SELECT
source_table.id AS id,
source_table.foo AS bar
FROM source_table
WHERE source_table.id = 1;
Is there any trick in MySQL's configuration to avoid this behaviour? I feel like it would create surprising tables.

This is the documented behaviour of insert ... select ..., so there is no way to configure it to avoid this behaviour:
MySQL creates new columns for all elements in the SELECT. For example:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> ENGINE=MyISAM SELECT b,c FROM test2;
This creates a MyISAM table with three columns, a, b, and c.

Related

How do I add data from different tables into one new table in mySQL?

CREATE TABLE CU_ORDER
( cordernumber INT PRIMARY KEY,
fname_lname VARCHAR(50) NOT NULL,
product_name VARCHAR(100) NOT NULL,
);
CREATE TABLE TRACKING_NUMBER
( trnumber INT PRIMARY KEY
);
INSERT INTO CU_ORDER VALUES(456, 'John Doe' , Table);
INSERT INTO TRACKING_NUMBER(276734673);
I am trying to created a table called Package and in the table it will have all the items from cu_order and all the items from tracking_number. How will I add all of the attributes of this table to one table. What am I doing wrong?
CREATE TABLE PACKAGE
( orderno INT PRIMARY KEY,
fname VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
trno INT PRIMARY KEY);
INSERT INTO PACKAGE (........
The two tables do not seem to have a relation, so, presumably, you want a cartesian product of both tables. If so, you can use the insert ... select ... syntax with a cross join:
insert into package(orderno, fname, name, trno)
select
co.cordernumber,
co.fname_lname,
co.product_name,
tn.trnumber
from cu_order co
cross join tracking_number tn
This inserts all possible combinations of rows from both source tables in the target table.
You should also fix the declaration of the package table: yours has two primary keys, which is not allowed. Instead, you probably want a compound primary key made of both columns:
create table package (
orderno int,
fname varchar(50) not null,
name varchar(100) not null,
trno int,
primary key(orderno, trno)
);
You can create a new table from the data of another table (or several tables) by appending a SELECT statement to the CREATE TABLE statement.
However, your two source tables are missing the 1:1 relation allowing this to work, which I assume is the cordernumber of CU_ORDER. It appears the table TRACKING_NUMBER is missing a 'cordernumber' column.
CREATE TABLE TRACKING_NUMBER (
trnumber INT PRIMARY KEY,
cordernumber INT
);
After you added the column 'cordernumber' to TRACKING_NUMBER, you can create the new table PACKAGE with:
CREATE TABLE PACKAGE (
orderno INT PRIMARY KEY,
fname VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
trno INT PRIMARY KEY
)
SELECT
CU_ORDER.cordernumber AS orderno,
CU_ORDER.fname_lname AS fname,
CU_ORDER.product_name AS name,
TRACKING_NUMBER.trnumber AS trno
FROM CU_ORDER, TRACKING_NUMBER
WHERE CU_ORDER.cordernumber=TRACKING_NUMBER.cordernumber;

I unable to Insert a value from a char that has been CAST as Integer and added by 1

I convert an id which is in a char column datatype. after that, I want to add it by 1 (plus 1).
Could you help me? why my query is not working?
query:
INSERT INTO `countries` (`id`, `country_name`) VALUES ((SELECT MAX(CAST(`id` as INTEGER)) AS `max_id` FROM `countries`) + 1, 'India');
The following would run:
INSERT INTO `countries` (`id`, `country_name`)
SELECT MAX(CAST(`id` as INTEGER)) + 1, 'India'
FROM `countries`;
But I think it would be easier if you just make the id column an AUTO_INCREMENT.
This is not how you should be doing identifiers.
If you want incrementing id values, you want to use the AUTO_INCREMENT feature when creating your table.
Your way is dangerous, there's always a possibility of two transactions running at the same time picking the same "next ID".
Just create a table with the flag on:
CREATE TABLE countries (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO countries (`name`) VALUES ('India');

Using SQL Sub-queries in an INSERT Statement

Here are the two tables created:
CREATE TABLE category_tbl(
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
subcategory varchar(255) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT nameSubcategory UNIQUE KEY(name, subcategory)
) ENGINE=InnoDB;
CREATE TABLE device(
id INT NOT NULL AUTO_INCREMENT,
cid INT DEFAULT NULL,
name VARCHAR(255) NOT NULL,
received DATE,
isbroken BOOLEAN,
PRIMARY KEY(id),
FOREIGN KEY(cid) REFERENCES category_tbl(id)
) ENGINE=InnoDB;
Below is the instruction that was given to me:
-- insert the following devices instances into the device table (you should use a subquery to set up foriegn keys referecnes, no hard coded numbers):
-- cid - reference to name: phone subcategory: maybe a tablet?
-- name - Samsung Atlas
-- received - 1/2/1970
-- isbroken - True
I'm getting errors on the insert statement below from attempting to use a sub-query within an insert statement. How would you solve this issue?
INSERT INTO devices(cid, name, received, isbroken)
VALUES((SELECT id FROM category_tbl WHERE subcategory = 'tablet') , 'Samsung Atlas', 1/2/1970, 'True');
You have different table name in CREATE TABLE and INSERT INTO so just choose one device or devices
When insert date format use the good one like DATE('1970-02-01')
When insert boolean - just TRUE with no qoutes I beleive.
http://sqlfiddle.com/#!9/b7180/1
INSERT INTO devices(cid, name, received, isbroken)
VALUES((SELECT id FROM category_tbl WHERE subcategory = 'tablet') , 'Samsung Atlas', DATE('1970-02-01'), TRUE);
It's not possible to use a SELECT in an INSERT ... VALUES ... statement. The key here is the VALUES keyword. (EDIT: It is actually possible, my bad.)
If you remove the VALUES keyword, you can use the INSERT ... SELECT ... form of the INSERT statement statement.
For example:
INSERT INTO mytable ( a, b, c) SELECT 'a','b','c'
In your case, you could run a query that returns the needed value of the foreign key column, e.g.
SELECT c.id
FROM category_tbl c
WHERE c.name = 'tablet'
ORDER BY c.id
LIMIT 1
If we add some literals in the SELECT list, like this...
SELECT c.id AS `cid`
, 'Samsung Atlas' AS `name`
, '1970-01-02' AS `received`
, 'True' AS `isBroken`
FROM category_tbl c
WHERE c.name = 'tablet'
ORDER BY c.id
LIMIT 1
That will return a "row" that we could insert. Just precede the SELECT with
INSERT INTO device (`cid`, `name`, `received`, `isbroken`)
NOTE: The expressions returned by the SELECT are "lined up" with the columns in the column list by position, not by name. The aliases assigned to the expressions in the SELECT list are arbitrary, they are basically ignored. They could be omitted, but I think having the aliases assigned makes it easier to understand when we run just the SELECT portion.

creating table from two different table

I am creating table from two different table with query:
create table post_table as
( select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
primary key (t1.id, t2,hash))
what's syntax error here?
post_data
----
url varchar(255) No
desc varchar(2048) No
preview varchar(255) No
img_url varchar(128) No
title varchar(128) No
hash varchar(128) No // This is one
rate varchar(20) Yes NULL
user_record
id varchar(40) No //This is 2nd
name varchar(50) Yes NULL
email varchar(50) Yes NULL
picture varchar(50) No
UPDATE:
create table post_table (
id VARCHAR(40), url varchar(255), preview varchar(255) , img_url varchar(128), title varchar(128), hash varchar(128), rate varchar(20)
primary key (t1.id, t2,hash));
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2;
Formatting the CREATE TABLE statement so we can see the ( ) pairing:
create table post_table as (
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url, t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
primary key (t1.id, t2,hash)
)
We can see that the primary key is being attached to the select statement.
Beyond that there are specific restrictions around general CREATE TABLE syntax can be used in a CREATE TABLE ... SELECT statement.
From: http://dev.mysql.com/doc/refman/5.1/en/create-table-select.html
The ENGINE option is part of the CREATE TABLE statement, and should
not be used following the SELECT; this would result in a syntax error.
The same is true for other CREATE TABLE options such as CHARSET.
You can how ever select keys by using syntax similar to:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> ENGINE=MyISAM SELECT b,c FROM test2;
So with your query re-work it to define the column types first, then the keys, then the select statement last. We don't know your data types but it would look something similar to:
create table post_table (
id DATATYPE, url DATATYPE, desc DATATYPE...
primary key (t1.id, t2,hash))
)
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
You have put key definition BEFORE select.
Also you can't do key definition without fields, so if you need keys, you have put all table structure.
http://dev.mysql.com/doc/refman/5.1/en/create-table.html
Other way is create index after creating table by use CREATE INDEX

adding unique values to existing table in mySql

Good Day
I created a table, NEW_TABLE, from some of another table columns ,OLD_TABLE.
I added a new column ID of type double
I want to fill the values of the ID column with unique values and then make it the the NEW_TABLE key.
Is there a way to do this in MySQL with a query or a set command?
I tried something like this:
Insert into NEW_TABLE
(select generateId() , col1, col2
from ORIGINAL_TABLE)
Usually you set the field to be an auto increment field when it is defined. To do so afterwards, you can use:
ALTER TABLE NEW_TABLE MODIFY ID int(10) unsigned NOT NULL auto_increment;
To then insert an new record and for it to automatically get an assigned ID, merely omit the field from the insert.
try this:
Insert into NEW_TABLE
(select #row := #row + 1 as generateId, col1, col2
from ORIGINAL_TABLE, (SELECT #row := 0)row)
You should use autoincrement and an integer field (is there any reason for you to want a double key there?):
CREATE TABLE NEW_TABLE (
id INT NOT NULL AUTO_INCREMENT,
col1 CHAR(30) NOT NULL,
col2 CHAR(30) NOT NULL,
PRIMARY KEY (id)
)
Why did you choose DOUBLE and not an integer datatype?
ALTER TABLE NEW_TABLE
MODIFY ID INT UNSIGNED NOT NULL AUTO_INCREMENT ;
ALTER TABLE NEW_TABLE
ADD CONSTRAINT new_table_pk
PRIMARY KEY (ID) ;
and then:
INSERT INTO NEW_TABLE
(col1, col2)
SELECT col1, col2
FROM ORIGINAL_TABLE ;