I know that in MySQL you can do something like SELECT foo AS bar FROM TABLE t; I'm trying to do something to the effect of SELECT command1 FROM table1 AS foo, command2 FROM table2 AS bar, (foo-bar) AS difference; but MySQL doesn't let me do that. Is there a way to do this in MySQL or will I need to get some extension? Thanks in Advance!
Schema
create table t1
( id int auto_increment primary key,
thing varchar(100) not null
);
create table t2
( id int auto_increment primary key,
descr varchar(100) not null
);
insert t1(thing) values ('cat'),('dog');
insert t2(descr) values ('meow'),('likes bones');
Query
select t1.thing,t2.descr into #var1,#var2
from t1
join t2
on t2.id=t1.id
where t1.id=2; -- to avoid Error 1172: Result consisted of more than one row
View vars
select #var1 as thing,#var2 as descr;
+-------+-------------+
| thing | descr |
+-------+-------------+
| dog | likes bones |
+-------+-------------+
The important part of selecting into vars like above is to limit the resultset to 1 row max.
Related
I've got a table with multiple duplicated entries in a column and I want to put these entries in a new table and connect these tables with a foreign key in the initial table.
Old Table:
table 1
| id | name | medium |
| 0 | xy | a |
| 1 | xz | b |
| 2 | yz | a |
new Table:
table 1 table2
| id | name | medium | | id | name |
| 0 | xy | 0 | | 0 | a |
| 1 | xz | 1 | | 1 | b |
| 2 | yz | 0 |
With CREATE ... SELECT I have a good tool to create a new table from the results of a query but I don't know how to change the entries from table1.medium to a foreign key based on the comparison to table2.medium. Is there any chance to do that?
You can do:
-- Create the second table
create table table2 (
id int primary key,
name varchar(255) unique
);
-- Insert rows into it
insert into table2
select row_number() over (order by medium), medium
from original
group by medium;
-- Use JOIN to create the first table and populate with the right ids
create table table1 as
select o.id, o.name, t2.id as medium
from original o join
table2 t2
on t2.medium = o.name;
Here is a db<>fiddle.
You can turn the id in table2 then into an auto_increment column:
alter table table2 modify column id int auto_increment;
It sounds like you can create Table2 but are having trouble changing Table1, updating the column type from char to int and creating a foreign key.
Easiest would be to rename Table1 to Table3 then create Table1 as you want, insert the data, then drop Table3.
If you need to modify the existing table, it will be a multi-step process.
Add new column 'medium_old' and copy existing values from medium
Drop the column 'medium' with the char type
Add the column 'medium' with the new int type
Update the new 'medium' values to the key from Table2 based on values in 'medium_old'
Add the foreign key constraint to 'medium'
There are two ways of doing it:
You recreate table1 with the new values in the medium column. Then you drop the old table1 and rename the new table. I would use this approach if medium column not only needs new values, but also needs to be converted to a new data type - this seems to be the case in the question. You already figured this approach out with create table ... as ...
Using multi-table update syntax, you can easily update a field in a table based on a field in another table. I would use this approach if you do not need to change the data type of the medium column. See this SO question on how to do this update.
If you are running mysql version 8.0 or above you can do below and use window function ROW_NUMBER.
Source
CREATE TABLE TABLE2
AS
SELECT ID,NAME(
SELECT ID, MEDIUM AS NAME,ROW_NUMBER()OVER(PARTITION BY MEDIUM ORDER BY ID) AS ROWW FROM TABLE1)
WHERE ROWW=1;
-- Adds a new column into your TABLE1 for MEDIUM's int values
ALTER TABLE TABLE1 ADD COLUMN MEDIUMINT INT;
-- Update MEDIUMINT according to your TABLE2 values.
UPDATE TABLE1 S1
JOIN TABLE2 S2 ON TABLE1.MEDIUM=S2.NAME
SET S1.MEDIUMINT=S2.ID;
-- Drops MEDIUM column from TABLE1
ALTER TABLE TABLE1 DROP COLUMN MEDIUM;
-- Rename MEDIUMINT column to MEDIUM
ALTER TABLE TABLE1 RENAME COLUMN MEDIUMINT TO MEDIUM;
I will not go deep in details.
I have Java program which is creating tables in Database. The thing is that when table is created one of the fields get default value. So when I am adding elements to this field I want to select default value. Now loading of all element's ID is:
SELECT distinct(codeKind) FROM [table_name];
I want to be something like this:
SELECT [default value of column codeKind] from [table_name];
I checked many of answer of other similiar questions but none of them is OK.
Thanks.
I also find solution:
select COLUMN_DEFAULT
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA='my_db' and TABLE_NAME='my_table' and COLUMN_NAME='my_column'
Maybe this
drop table if exists t;
create table t
(id int auto_increment primary key,size int, sizecaption1 int default 10, sizecaption2 int, sizecaption3 int);
insert into t (id,size) values
(1,22);
insert into t values
(2,22,22,22,22),
(3,22,22,30,20),
(4,22,1,2,3);
select * from t where sizecaption1 =
(
select column_default from information_schema.columns
where table_name = 't' and table_schema = 'sandbox' and column_default is not null
) ;
+----+------+--------------+--------------+--------------+
| id | size | sizecaption1 | sizecaption2 | sizecaption3 |
+----+------+--------------+--------------+--------------+
| 1 | 22 | 10 | NULL | NULL |
+----+------+--------------+--------------+--------------+
1 row in set (0.02 sec)
use coalesce
select coalesce(codeKind,<def_value>)
Alternatively you can set a fixed value for table's creation DDL such as
create table my_table ( my_column default 0, col2 int .... ) , if you leave the column value as blank in the insert statement, then the value is automatically populated as zero.
TABLE 1
+----+-------+-------+-------+
| uid | color | brand | model |
+----+-------+-------+-------+
| 10 | 1 | 2 | 1 |
+----+-------+-------+-------+
TABLE 2
+----+-------+-------+-------+
| uid | quantity |model |color|
+----+-------+-------+-------+
| 25 | 2 | 2 | 1 |
+----+-------+-------+-------+
I have many tables like this where the uid column is present in every table.I have a value in a variable, say var1=25. I want to check whether var1 value matches with any of the uid value of any table.If it matches I want to print the table name. Can anyone help me with this?
I tried doing this and I found
SELECT `COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='yourdatabasename'
AND `TABLE_NAME`='yourtablename';
But this is not giving what I want since I want to select all the tables in a database irrespective of the table name.If in future any table is added then it should also get selected.
At first, information_schema table doesn't have specific tuple data.
I suggest you to consider different design.
A. Make a meta table and use triggers(attached to base tables) to maintain meta table.
CREATE TABLE meta_table (
id INT AUTO_INCREMENT,
uid INT,
table_name VARCHAR(50)
);
# When you need to add new table (table 3)
CREATE TABLE table_3 (
uid INT,
field1 INT,
field2 INT,
field3
);
DELIMITER $$
CREATE TRIGGER table_3_insert
AFTER INSERT ON table_3
FOR EACH ROW
BEGIN
INSERT INTO meta_table (uid, table_name)
VALUE (NEW.uid, "table_3");
END$$
DELIMITER ;
# If data in `table_3` might be changed or deleted,
# then create trigger for `delete` and `update`
B. Use only one table with unstructured field and parse data field in your application
CREATE TABLE table (
uid INT,
table_type INT,
data VARCHAR(255)
);
INSERT INTO table (10, 1, '{"color":1,"brand":2,"model":1}');
INSERT INTO table (10, 2, '{"quantity":2,"model":2,"color":1}');
As you mentioned "any table can be added" often, I strongly recommend B solution. It is not good design that changing schema(creating table) often.
I need to transfer the data of 2 tables into the new table, here is the simplified table.
Table 1
user_id_slot_1 | user_id_slot_2 | some_column | some_column_2
Table 2
user_id_slot_1 | user_id_slot_2 | some_column | some_column_2
Note:
Data from table 1 and 2 that I need to transfer/copy is almost identical.
user_id_slot_1 and user_id_slot_2 either one of them should be
empty/null.
Column's names are different from the actual database.
New Table
id | user_id | some_column | some_column_2
How can I transfer the data from Table 1 and 2?
How can I merged the column user_id_slot_1 and user_id_slot_2 into one and transfer it to user_id.
UPDATE:
I do not need to transfer/copy the ids of the Table 1 and 2, New Table needs to auto increment it.
Assuming that the new table already exists, you can use INSERT INTO ... SELECT to move the data. I have used UNION ALL here under the assumption that you don't want to remove duplicates between the two source tables should they occur.
INSERT INTO new_table (`user_id`, `some_column`, `some_column_2`)
SELECT COALESCE(user_id_slot_1, user_id_slot_2),
some_column,
some_column2
FROM table1
UNION ALL
SELECT COALESCE(user_id_slot_1, user_id_slot_2),
some_column,
some_column2
FROM table2
Notes: The COALESCE(user_id_slot_1, user_id_slot_1) term in the above query will choose user_id_slot_1 if it be not NULL otherwise it will choose user_id_slot_2. This should be fine assuming that one and only one will be non NULL for every record.
Assuming that the new_table table has its id column set to auto increment, then MySQL will handle assigning these values for you. All you need to do is omit a value for id in new_table and MySQL will handle the rest.
You should create the new table using something like this:
CREATE TABLE new_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
some_column VARCHAR(50) NOT NULL,
some_column_2 VARCHAR(50) NOT NULL
)
Is this what you want?
create table3 as
select id, coalesce(user_id_slot_1, user_id_slot_2) as user_id,
some_column, some_column_2
from table1
union all
select id, coalesce(user_id_slot_1, user_id_slot_2) as user_id,
some_column, some_column_2
from table2;
New to MySQL and trying to carry something over from R.
I have a data table with two columns, similar to the following, with a level-2 id and a nested id:
level2id | nestedid |
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
...
I want to restructure the data using MYSql in a new table like this:
level2id | nestedid1 | nestedid2 | nestedid3 |
1 | 1 | 2 | 3 |
2 | 1 | 2 | |
...
This is so that I can later perform joins to extract information on the nested ids to create aggregate values for variables that relate to the level2 id. Trivial to do in R using reshape for "time-varying" data, but can't find an obvious solution to this particular format (i.e. where the data are not organized in terms of attribute names and attribute values in columns. Thanks in advance!
While you cannot do it as a SELECT you may achieve this using inserts which only works if the primary key ls level2id or you have a unique index on that level2id
Table structure
CREATE TABLE `table2` (
`level2id` int(11) NOT NULL DEFAULT '0',
`nestedid1` int(11) NOT NULL,
`nestedid2` int(11) NOT NULL,
`nestedid3` int(11) NOT NULL,
PRIMARY KEY (`level2id`)
) ENGINE=InnoDB;
The insert SQL statements replace table1 with your old table
INSERT INTO table2 (level2id, nestedid1) SELECT level2id, nestedid FROM table1 WHERE nestedid = 1 ON DUPLICATE KEY UPDATE nestedid1 = nestedid;
INSERT INTO table2 (level2id, nestedid2) SELECT level2id, nestedid FROM table1 WHERE nestedid = 2 ON DUPLICATE KEY UPDATE nestedid2 = nestedid;
INSERT INTO table2 (level2id, nestedid3) SELECT level2id, nestedid FROM table1 WHERE nestedid = 3 ON DUPLICATE KEY UPDATE nestedid3 = nestedid;
The ON DUPLICATE KEY UPDATE is a MySQL extension more details here http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
I had a similar issue.
Maybe you want to have a look at dynamic pivoting in sql.
Dynamic pivot table with multiple columns in sql server. However I really do not recommend if you can just use a reshape command in R.
You may use MySQL to create a MySQL program that will fix this:
USE test;
/*Create long input table 'test' with variables of varying length*/
DROP TABLE nums;
CREATE TABLE nums (id INT(2));
INSERT INTO nums
VALUES
(0), (1), (2), (3), (4), (5), (6), (7);
DROP TABLE test;
CREATE TABLE test (id INT(2), var VARCHAR(5), attribute VARCHAR(6), PRIMARY KEY (id, var));
INSERT INTO test
SELECT nums3.*, REPEAT(CHAR(97+RAND()*24),CAST(6.*RAND() AS INT)) AS attribute
FROM (SELECT DISTINCT nums2.id1 as id, CONCAT('var', LPAD(CAST(16.*RAND() AS INT),2,'0')) AS var
FROM (SELECT DISTINCT nums.id as id1, nums1.id as id2 FROM nums, nums as nums1) AS nums2) AS nums3;
/*Create SQL program to convert long to wide format (R: reshape)*/
SELECT DISTINCT CONCAT('DROP TABLE result;\nCREATE TABLE result (id INT(2),
', GROUP_CONCAT(CONCAT(field) SEPARATOR ', '), ');')
FROM
(SELECT DISTINCT CONCAT(var, CONCAT(' VARCHAR(', max(length(attribute)), ')')) AS field
FROM test GROUP BY var) AS fields
UNION
SELECT CONCAT("INSERT INTO result \nSELECT DISTINCT test.id, ", GROUP_CONCAT(var SEPARATOR '.attribute, '),
".attribute FROM (SELECT DISTINCT id FROM test) AS test")
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars
UNION
SELECT CONCAT("LEFT JOIN test AS ", var, " ON test.id = ", var, ".id AND ", var, ".var=", '"', var, '"' )
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars
UNION
SELECT ";" ;
/*Copy output to screen editor, delete '|' symbols and superfluous white spaces.
Then copy to MySQL prompt, run by pressing 'enter' key and view 'result'*/