Insert into table from another with different columns count (MySQL) - mysql

Question, why this dose not work?
create table one (a int(1) default 1, b int(2));
create table two (b int(1));
insert into one select * from two;
error:
Column count doesn't match value count at row 1
a know it, a can count, but why, philosophically?
database knows, what the name of inserting column from table two is b, knows that the column a in table one has a default value equal 1..
so, what problem of executing this query?
And general - How can i do this differently, not manual, without information of a columns and their count, if this way is impossible?
I know this:
table two always have all the same columns, that the table one have. But table one have another columns too, that have a some default values.
Is there some way to do that? insert all data from two in one, and fill the remaining columns by some default or other values!
Need help!
Thank you very match!

When you run:
insert into one
select * from two;
The SQL engine automatically puts in the columns that are implied.
For the insert, this is the list of columns in declaration order.
For the *, this is the list of columns in declaration order.
There is no "matching" of columns by names, only lists of columns in each table.
So, the query is really:
insert into one(a, b)
select b from two;
That looks like an error to me.
Moral of the story? Write that code that you intend. Always include columns lists, particularly for insert statements. So write:
insert into one(b)
select b from two;

Related

MySQL - Copying partial data from one table to another

This may be a silly question, and I understand why I'm getting the result that I am, however, I thought mySQL acted differently and I can't finish the documentation to tell me otherwise.
I have 2 basic tables as follows:
CREATE TABLE test ( num INT, time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP );
CREATE TABLE test_to_copy ( num INT );
I then create a single entry into the test_to_copy table:
INSERT INTO test_to_copy VALUES ( 12 );
Now I try and copy the table test_to_copy to test like so:
INSERT INTO test SELECT * FROM test_to_copy;
The error that keeps getting thrown is
"Column count doesn't match value count at row 1".
I know that it is complaining that the number of columns in both tables does not match meaning it does not know what variable we are assigning our copy to, however, should it not be a case where the time is created automatically i.e. defaulted if nothing is inserted when we do the copy rather than throw the error?
Due to constraints, I can no longer have the time in both tables, and I must do a SELECT * on the test_to_copy table as there are over 50 columns, and i'm wondering is there an easy way around this?
This is another variation of a frequent question: "can I query *-except-for-one-column?"
No, there is no wildcard-with-exceptions syntax in SQL. The * wildcard means all columns. If you don't want all columns, you must name the columns explicitly.
If you have a variety of columns because this method may be used for more than one table, you can get the list of columns for any given table from INFORMATION_SCHEMA.COLUMNS and use that information to build a dynamic SQL query.
Here's a way you can produce the list of columns:
SELECT
GROUP_CONCAT(
CONCAT('`', column_name, '`')
) AS _cols
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='mydatabase' AND TABLE_NAME='mytable'
AND COLUMN_NAME NOT IN ('time'); -- or other columns to exclude
See also:
Select all columns except one in MySQL?
SQL exclude a column using SELECT * [except columnA] FROM tableA?
INSERT INTO test (num)
SELECT num
FROM test_to_copy

insert in database with column number

i want to insert in a table using columns order not name
insert into tableName(1,2,5) values('val1','val2','val3');
i dont want to use
insert into tableName values('val1','val2','val3');
because the table does not contain just 3 columns
how can i do it
because columns name are encrypted so I can not rely on this
insert into tableX("cCGSvKJVQXnt8A==","aDOlOQrPfg==","qsdcx112")
values('val1','val2','val3');
is there any idea how can i deal with this
thank
You can't use the ordinal number of a column in an insert statement. However, you can accomplish what you're trying to do (insert values into specific columns in a table) using the column names instead.
Presume your table has five columns; I'm going to call them "Alpha", "Bravo", "Charlie", "Delta", and "Echo", since you haven't given us the schema for your table, but replace these names with the names of the columns actually in your table. I'm guessing that your third and fourth column (my "Charlie" and "Delta") are nullable. You can then insert a tuple/row in your table with the other three columns filled using syntax like this:
INSERT INTO TableName(Alpha, Bravo, Echo) VALUES ("val1", "val2", "val3");
If, per your comments above, your column names are unprintable characters (which is a terrible, terrible idea), you can explicitly insert NULLs into the missing columns:
INSERT INTO TableName VALUES ("val1", "val2", NULL, NULL, "val3");
but the weakness here is that, if additional columns are subsequently added to your table's schema, the insert statement will start failing.
You need to put the column names where you have the 1,2,5. You can't use the column number.
insert into tableName(1,2,5) values("val1","val2","val3");

Copy Data From One Database To Another In Same Table

I want to copy data from one database which has table named domains to another database which also has the table named domains to it.
I have tried doing it using phpmyadmin but it doesn't copy maybe because of Auto_increment values. it just doesn't get copied to another database.table.
I want to know what can be done in this regard? also I don't want to copy old ID(auto_increment) values from first database to another.
phpmyadmin response.
#1136 - Column count doesn't match value count at row 1
both the structures are same in the databases still this.
My Query.
INSERT INTO `site1`.`domains`
SELECT * FROM `site33`.`domains`
^ This much is fixed.
now comes the auto_increment problem I Get:
#1062 - Duplicate entry '1' for key 'PRIMARY'
You could do something like this:
INSERT INTO database2.table1 (field2,field3)
SELECT table2.field2,table2.field3
FROM table2;
Note:
Do not include the column which is auto increment in your insert and select statement.
Sql Fiddle example
You are using an insert statement that has an incorrect number of values, for instance:
for a table with columns a, b and c, these are all invalid:
INSERT INTO YourTable VALUES (1, 2);
INSERT INTO YourTable(b, c) VALUES (1, 2, 3);
INSERT INTO YourTable(a, b, c) VALUES (2, 3);
The number of columns in the column list must match the number of values in the value list.
You may only omit the column list, but only if you specify one value for each column and in the order in which the columns exist in the table. This is bad practice, though. It is better to always specify the exact columns you need.

MySQL index with two same columns

I have a table with several hundred million rows. One of the columns is `status` varchar(10).
Most values in the status are 1 character, some varying up to 10. However a subset of the values has a pattern of its own. A whole group of status values begin with a single character c followed by a number ranging from 0 to 10,000.
I would like to index this column with the following:
ALTER TABLE tbl ADD KEY (status(1), status);
This would be better than having two individual keys, one on status(1) (first character of the whole column) and second status. Together they would always be faster.
However MySQL prohibits me from creating such:
ERROR 1060 (42S21): Duplicate column name 'status'
How can I solve this?
There's really no reason to index status(1) independently of status. One index created on status should handle both situations equally well.
You could create a second column in your table and populate it with the first character of the other column and then create an index on each. However, this might have poor selectivity and not be all that useful.

SQL:- how to take Average of multiple(50) Columns with many null values in between, without listing 50 columns names in SQL?

how to take Average of multiple(50) Columns with many null values in between, without listing 50 columns names in SQL?I need more general way of handling such situation?
It sounds like you would need to transpose your current table to achieve this. As far as I know, there is no way to transpose a MySQL table without specifying the exact columns to be transposed. So I would say that the best way would be to retrieve a row (or rows, depending on your needs) with SELECT * FROM table and then calculate the average using the whatever scripting / programming language you are using.
I would do it like this
select (isnull(col1,0)+isnull(col2,0)+...+isnull(col50,0))/50 as averageval
from table
but it is clear that your table design is wrong. You should have a values table that contains these values.
This is what a correct design would look like:
maintable
----------
id int
valuetable
----------
mainkey int -- foreign key to maintable.id
valuenum int -- may not be needed goes from 1 to 50
value int
At some point you will need to list the columns. Sql will not know which columns to include in the calculation until it is told.
If you calculation is a more then "just one time" consider placing a computed column in the table to hold the calculation which is maintained by SQL.