Create new table with calculated data from another table - mysql

I'm going to do an regression analysis through my data chunks. For that I need to find out various values. For each data set I need to get N:count(X) sumX sumY sumX*X etc.
Separately I wrote queries for those operations like
SELECT COUNT(X) FROM table_name
SELECT SUM(X*X) FROM table_name
I need to create another table which a row contain count(X), sumX , sumX*X etc. How can I write that kind of query?

You can add multiple aggregates to the same query and use create table as:
create table yournewtable as
select count(x) cnt, sum(x*x) sumxx, sum(x) sumx
from table_name
SQL Fiddle Demo
This will return you a single row. If you need to break it apart, look into group by.

CREATE TABLE first and then use INSERT INTO
CREATE TABLE yourTableName
(
col1 int,
col2 int,
col3 int
);
INSERT INTO yourTableName (col1, col2, col3)
SELECT
(SELECT COUNT(X) FROM table_name),
(SELECT SUM(X) from table_name),
(SELECT SUM(X*X) from table_name)

Related

db.Prepare("INSERT INTO ? VALUES ()") not working [duplicate]

this is my problem: I want to check rows in a table which name is parameterized, something like table_X. The value of X comes from another table, so for example in my main table I have a column c_id and a column X, the table to join has name table_X, it EXISTS with no doubt, and it has the same column c_id, which I shall join on, to check if there are values of c_id in that table.
I've tried a view, but without success, because I can't put a parameterized table name in a view. I can parameterize where clauses and other things, but no table names.
I've tried a procedure, with
SET #q = CONCAT('select blabla from table_', X);
PREPARE stmt FROM #q;
EXECUTE stmt;
but procedures can't return values, and I need it, because I need to know if there is the c_id value in the parameterized table, else it is useless.
I've tried a function, but "Dynamic SQL is not allowed in stored function or trigger"
So what can I do to extract this data? I'm calling this view/function/whatever from PHP, and I know I can do it from PHP side, with two queries, but I need to do it db-side, for future implementations.
Is it possible?
NOTE: I can't modify the structure of the DB :) btw, it's the Limesurvey db, sounds like a crazy db structure, huh?
The only way, without dynamically building queries, is to hard code in every combination and pick out the one you want.
If the table name is a parameter to a stored procedure, this can be in IF blocks. But it feels clunky.
If the fields from each table are the same, you can union the tables together and select from those...
CREATE VIEW myUnifiedStructure AS
SELECT 'Table1' AS tableName, * FROM Table1
UNION SELECT 'Table2' AS tableName, * FROM Table2
UNION SELECT 'Table3' AS tableName, * FROM Table3
-- etc
SELECT * FROM myUnifiedStructure WHERE tableName = 'Table1'
If the fields are different in each table, you may only be interested in a subset of the fields...
CREATE VIEW myUnifiedStructure AS
SELECT 'Table1' AS tableName, field1 AS field1, field4 AS field2 FROM Table1
UNION SELECT 'Table2' AS tableName, field2 AS field1, field3 AS field2 FROM Table2
UNION SELECT 'Table3' AS tableName, field2 AS field1, field4 AS field2 FROM Table3
-- etc
Or you can pass in NULLs for fields that don't exist in the source table...
CREATE VIEW myUnifiedStructure AS
SELECT 'Table1' AS tableName, NULL AS field1, field2 AS field2 FROM Table1
UNION SELECT 'Table2' AS tableName, field1 AS field1, field2 AS field2 FROM Table2
UNION SELECT 'Table3' AS tableName, field1 AS field1, NULL AS field2 FROM Table3
-- etc
Why do you need separate tables like this? It's usually a sign of bad design. Wouldn't it just be easier to create a single table with an identifier field for whichever X` value that record belongs to, that you can join/filter on?
That'd reduce the query to something like
SELECT ...
FROM othertable
JOIN bigtable ON othertable.c_id = bigtable.c_id AND othertable.fieldName = bigtable.fieldName

mysql concatenate multiple existing tables into one new table

I've done some research but all of the examples that I've found seem too complicated given what I would like to do. I have multiple tables of archived data by year (e.g. archive_2013, archive_2012, etc.) and would like to create a new master table (archive_master) consisting of all of the data from all of the tables. The tables have no keys and only 2 columns, one varchar(120) and the other char(20). I'm hoping that this is as simple and straightforward as I think it is.
A simple UNION will do the trick:
SELECT col1, col2
FROM archive_2013
UNION ALL
SELECT col1, col2
FROM archive_2012
Combine it with an INSERT and you are done:
INSERT INTO full_archive
SELECT col1, col2
FROM archive_2013
UNION ALL
SELECT col1, col2
FROM archive_2012
So you want to create one new table?
You could use a simple INSERT INTO with a SELECT
See:
CREATE TABLE with SELECT
http://dev.mysql.com/doc/refman/5.0/en/create-table-select.html
INSERT INTO TABLE with SELECT
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
Example
You can create a new table:
create table 'xyz' select * from archive_2010;
insert into xyz select * from archive_2011;
INSERT INTO archive_master VALUES (SELECT * FROM archive_2013);

How can I copy table records unrepeatedly?

I have a table that contains some duplicate redords. I want to make records unique. I created a new table (say, destination) and I specified a unique column in it. How can copy records from table1 (source) such that, if the record inserted in the destination table, it does not insert it again.
You can use the "select into" construct and select insert only distinct rows, like this:
insert into table_without_dupes (column0, column1) select distinct column0, column1 from table_with_dupes
If you have autoincrement or other columns that makes the rows distinct, you can just leave them out of the insert and select parts of the statement.
Edit:
If you want to detect duplicates by a single column, you can use group by:
insert into table_without_dupes (column0, column1) select column0, column1 from table_with_dupes group by column0
MySQL will allow you to refer non-aggregated columns in select, but remember that the documentation says "The server is free to choose any value from each group", if you want to select one specific row of the groups, you might find this example useful.
Generic approach
insert into destination(col1,col2)
select DISTINCT col1,col2 from source as s where not exists
(select * from destination as d where d.col1=s.col1)
Edited
insert into destination(col1,col2)
SELECT distinct col1,col2 from source
Edited (Assuming col3 is duplicated and you want only one copy of it.)
insert into destination(col1,col2,col3,....,colN)
SELECT col1,col2,col3,...,colN from source as s1 inner join
(
select col1,col2,max(col3) as col3
from source
group by col1,col2
) as s2 on t1.col1=t2.col1 and t1.col2=t2.col2 and t1.col3=t2.col3
insert into <dest_table_name>
select distinct * from <source_table_name>;

TSQL aggregate functions to populate temp tables

I want to run a T-SQL script where I create a temp table that will be aggregated by a certain field of another table, call it table X. The remaining fields of this temp table will be populated by performing aggregate functions on the fields of table X. Then I would like to do a MERGE / WHEN MATCHED with my temp table on a different table (call it table Y) after I have populated the temp table.
How do I create this temp table and populate it with aggregate functions? (I have already coded the MERGE part of the problem).
to create a temp table you will can do the following:
create table #temp
(
id int,
col1 int
)
then you will write an INSERT INTO
INSERT INTO #temp
SELECT col1, sum(col2)
FROM yourTable
Once you have created your temp table you can use it in your store procedure.
What bluefeet posted, or:
with rsAggregated as
(
select id, sum(x)
from tableX
group by id
)
merge...
Or, not seeing your merge statement, just
merge tableY using
(
select id, sum(x)
from tableX
group by id
) rsAggregated
on rsAggregated.id = tableY.id
when matched
...
when not matched
...
You can do the whole thing with one SELECT statement
SELECT col1 AS ID, sum(col2) AS col1 INTO #temp FROM yourTable

DELETE Difference NOT IN vs NOT EXISTS

I have two scenarios represented below, SCENARIO 1 works as well as SCENARIO 2 but are both those SCENARIOS achieving the Same Objective, Note in both Scenario's otherTbl is static
SCENARIO 1
CREATE TABLE `tbl`(
col1 VARCHAR(255),
PRIMARY KEY(col1)
) ENGINE='InnoDb';
Here is my set of queries that I run previously that make sense and run fine.
#Create an exact copy of the `tbl`
CREATE TEMPORARY TABLE `tmp_tbl`( .. SAME AS `tbl` .. );
#Add grouped records from another table into `tmp_table`
INSERT INTO tmp_tbl SELECT col1 FROM otherTbl GROUP BY col1;
#Delete the tables that donot exist any more int the `otherTbl`
DELETE FROM tbl WHERE tbl.col1 NOT IN (SELECT col1 FROM tmp_tbl);
SCENARIO 2
In this scenario the difference is only of the columns, As you can see all of them are primary Keys
CREATE TABLE `tbl`(
col1 VARCHAR(255),
col2 VARCHAR(255),
col3 VARCHAR(255),
PRIMARY KEY(col1, col2, col3)
) ENGINE='InnoDb';
Here are the new set of Queries
#Create an exact copy of the `tbl`
CREATE TEMPORARY TABLE `tmp_tbl`( .. SAME AS `tbl` .. );
#Add grouped records from another table into `tmp_table`
INSERT INTO tmp_tbl
SELECT col1, col2, col3 FROM otherTbl GROUP BY col1, col2, col3;
#Delete the tables that donot exist any more int the `otherTbl`
DELETE FROM tbl WHERE NOT EXISTS(SELECT col1, col2, col3 FROM `tmp_tbl`);
The question simply is, Do they achieve the same conclusion HENCE if we replace the delete query from NOT IN to NOT EXISTS in SCENARIO 1 it will still work the same way.
******SIMPLE VERSION******
Is:
DELETE FROM `tbl` WHERE tbl.col1 NOT IN (SELECT col1 FROM tmp_tbl);
Equall To:
DELETE FROM `tbl` WHERE NOT EXISTS(SELECT col1 FROM `tmp_tbl`);
I haven't tested it, but they are most likely not equivalent. The NOT EXISTS form would make sense if used with a correlated subquery. But your subquery doesn't contain any reference to the outer query, so probably the second form won't delete any rows at all.
Also, presence of NULLs in the table may make these two forms act very differently.
These two queries should, to my knowledge, achieve the same results (since the query checks for the same data - only the second one does it in a more elegant manner maybe).