MySQL: Obtain Fields From Multiple Tables Each Result Represented As A Row - mysql

I have multiple tables with this structure:
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| nick | char(25) | NO | PRI | NULL | |
| id | int(11) | NO | | NULL | |
| cooldown | datetime | NO | | NULL | |
+----------+----------+------+-----+---------+-------+
I would like to obtain all of the id fields from all of these tables given a nick. These tables (lets call them table1, table2, table3) may or may not be empty. What is the best way to do this in one query?
My desired output would look like:
+-------+
| id |
+-------+
| 15679 |
| 72620 |
+-------+

You need a UNION query:
SELECT id FROM table1 WHERE nick='nick'
UNION
SELECT id FROM table2 WHERE nick='nick'
UNION
SELECT id FROM table3 WHERE nick='nick'
UNION will only return unique rows, if you want your query to return duplicates you can use UNION ALL instead.

Select Id from table1 where nick=nick
UNION
Select Id from table2 where nick=nick
UNION
...
UNION
...

Related

Summing all 5 table values to form new table?

I have 5 tables with following properties,
+--------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+-------------+------+-----+---------+-------+
| actor_id | int(11) | YES | MUL | NULL | |
| activity_object_id | int(11) | YES | MUL | NULL | |
| interest_level | tinyint(4) | YES | | 10 | |
| feed_view | smallint(6) | YES | | 0 | |
| quick_view | smallint(6) | YES | | 0 | |
| page_view | smallint(6) | YES | | 0 | |
| fullscreen_view | smallint(6) | YES | | 0 | |
| reserved1 | int(11) | YES | | NULL | |
| reserved2 | int(11) | YES | | NULL | |
| reserved3 | int(11) | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+--------------------+-------------+------+-----+---------+-------+
How we can create new temporary table which is sum of all the 5 table values. activity_object_id is unique and one table might contain activity_object_id while the other one may not.
table1 has one active_object_id say 'gowthamkey', table2 has same key 'gowthamkey', and table3 might not have 'gowthamkey'. So I want to sum up all the tables values into new table, so that it has one key 'gowthamkey' where values are sum of:
feed_view,quick_view,page_view,fullscreen_view,reserved1,reserved2,reserved3 except actor_id, interest_level, created_at, updated_at.
Here is my query as per #bummer answer:
CREATE TABLE actor_activity_object_stats_temp_7_days_12 AS
select actor_id, activity_object_id, interest_level, SUM(feed_view) AS feed_view, SUM(quick_view) AS quick_view, SUM(fullscreen_view) as fullscreen_view
from (
select * from actor_activity_object_stats_temp_2016_04_29
union all,
select * from actor_activity_object_stats_temp_2016_04_30
union all,
select * from actor_activity_object_stats_temp_2016_05_01
union all,
select * from actor_activity_object_stats_temp_2016_05_02
union all,
select * from actor_activity_object_stats_temp_2016_05_03
union all,
select * from actor_activity_object_stats_temp_2016_05_04
union all,
select * from actor_activity_object_stats_temp_2016_05_05
union all,
select * from actor_activity_object_stats_temp_2016_05_06
union all,
select * from actor_activity_object_stats_temp_2016_05_07
union all,
select * from actor_activity_object_stats_temp_2016_05_08 ) AS X
group by activity_object_id
Start with a UNION, then use SUM() to add all the values from all the tables for the same activity_object_id.
CREATE TABLE new_table
AS SELECT activity_object_id, SUM(feed_view) AS feed_view, SUM(quick_view) AS quick_view, ...
FROM (SELECT * FROM table1
UNION ALL
SELECT * FROM table2
UNION ALL
SELECT * FROM table3
...) AS x
GROUP BY activity_object_id
I believe this should solve your issue.
create table new_table
as
select * from table1
union
select * from table2
union
select * from table3
union
select * from table4
union
select * from table5)
here's a sql fiddle to illustrate.

Mysql intersection query performance

I am quite new to mysql. I have 2 identical mysql tables which have 50K rows (70 columns) each. Those tables are updated everyday by a datafeed. I need to execute some nested queries like intersections / substractions etc.
One of the queries I try to use is as below.
But it doesn't work properly. Either it takes 5 min. to 10 min. (through terminal) or it does not respond back.
SELECT *
FROM table1
WHERE table1.sku IN (SELECT t1.sku
FROM ((SELECT DISTINCT sku
FROM table2)
UNION ALL
(SELECT DISTINCT sku
FROM table1)) AS t1
GROUP BY sku
HAVING Count(*) >= 2)
How can I make it work faster/properly? How should I configure the tables/columns (index, primary key etc.) Or do I need to make any tuning on the mysql server?
I tried several things. I created indexes on the 'sku' which are varchar(75)
columns. My database server runs on a 1 CoreProcessor (Digital Ocean) server
with 512MB Memory.
--- query with 'EXPLAIN'
+----+--------------------+-----------------------+-------+---------------+---------+---------+------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------------------+-------+---------------+---------+---------+------+-------+---------------------------------+
| 1 | PRIMARY | table1 | ALL | NULL | NULL | NULL | NULL | 30260 | Using where |
| 2 | DEPENDENT SUBQUERY | <derived3> | ALL | NULL | NULL | NULL | NULL | 65677 | Using temporary; Using filesort |
| 3 | DERIVED | table2 | range | NULL | sku_idx | 227 | NULL | 31016 | Using index for group-by |
| 4 | UNION | table1 | range | NULL | sku | 227 | NULL | 30261 | Using index for group-by |
| NULL | UNION RESULT | <union3,4> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------------+-----------------------+-------+---------------+---------+---------+------+-------+---------------------------------+
If I understand this particular query correctly, you are trying to display all the records from table1 which have a corresponding sku in table2.
That can be achieved by a much simpler query:
SELECT *
FROM table1
WHERE table1.sku IN (SELECT DISTINCT table2.sku FROM table2 )
GROUP BY table1.sku
Or, with joins:
SELECT table1.*
FROM table1
INNER JOIN table2 ON table1.sku = table2.sku
GROUP BY table1.sku
This should work in an instant if you have indexes on table1.sku and table2.sku

MySQL merge results into table from count of 2 other tables, matching ids

I've got 3 tables: model, model_views, and model_views2. In an effort to have one column per row to hold aggregated views, I've done a migration to make the model look something like this, with a new column for the views:
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| [...] | | | | | |
| views | int(20) | YES | | 0 | |
+---------------+---------------+------+-----+---------+----------------+
This is what the columns for model_views and model_views2 look like:
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | smallint(5) | NO | MUL | NULL | |
| model_id | smallint(5) | NO | MUL | NULL | |
| time | int(10) unsigned | NO | | NULL | |
| ip_address | varchar(16) | NO | MUL | NULL | |
+------------+------------------+------+-----+---------+----------------+
model_views and model_views2 are gargantuan, both totalling in the tens of millions of rows each. Each row is representative of one view, and this is a terrible mess for performance. So far, I've got this MySQL command to fetch a count of all the rows representing single views in both of these tables, sorted by model_id added up:
SELECT model_id, SUM(c) FROM (
SELECT model_views.model_id, COUNT(*) AS c FROM model_views
GROUP BY model_views.model_id
UNION ALL
SELECT model_views2.model_id, COUNT(*) AS c FROM model_views2
GROUP BY model_views2.model_id)
AS foo GROUP BY model_id
So that I get a nice big table with the following:
+----------+--------+
| model_id | SUM(c) |
+----------+--------+
| 1 | 1451 |
| [...] | |
+----------+--------+
What would be the safest route for pulling off commands from here on in to merge the values of SUM(c) into the column model.views, matched by the model.id to model_ids that I get out of the above SQL query? I want to only fill the rows for models that still exist - There is probably model_views referring to rows in the model table which have been deleted.
You can just use UPDATE with a JOIN on your subquery:
UPDATE model
JOIN (
SELECT model_views.model_id, COUNT(*) AS c
FROM model_views
GROUP BY model_views.model_id
UNION ALL
SELECT model_views2.model_id, COUNT(*) AS c
FROM model_views2
GROUP BY model_views2.model_id) toupdate ON model.id = toupdate.model_id
SET model.views = toupdate.c

MySQL Pivot Field Names to values in row

I'm new to pivoting, so I came here to get some advice on this. I have a table with fields benchmarkname and value. However, another table is populated differently and out of my control: it has each benchmarkname as its own field in the table, with the row value being the value. The layout is below:
Table 1
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| stream | double | YES | | NULL | |
| pisec | double | YES | | NULL | |
| iozws | double | YES | | NULL | |
| iozwb | double | YES | | NULL | |
| iozrs | double | YES | | NULL | |
| iozrb | double | YES | | NULL | |
Table 2
| BenchmarkName | varbinary(43) | YES | | NULL | |
| Value | decimal(14,0) | YES | | NULL | |
My question is: how do I convert the first table to look like second dynamically? I believe the answer lies in a pivot, but I am unsure.
I think you want to unpivot the first table. UNPIVOTing takes the data from your columns and converts it into rows. MySQL does not have unpivot so you will have to use a UNION ALL query:
select 'stream' BenchmarkName, stream value
from table1
union all
select 'pisec' BenchmarkName, pisec value
from table1
union all
select 'iozws' BenchmarkName, iozws value
from table1
union all
select 'iozwb' BenchmarkName, iozwb value
from table1
union all
select 'iozrs' BenchmarkName, iozrs value
from table1
union all
select 'iozrb' BenchmarkName, iozrb value
from table1

mysql union different databases but the same schema

as picture(phpmyadmin),I have tables in the database week1 the tables are now empty.
I have another databases with exactly the same sql schema w1moninside and w1monoutside
but they have values.
I want to union these two and insert them in week1
what should I do?
I inserted the picture just for clearance.unoin for one of the tables for example the first one, data
is enough for me
Thanks.
mysql> describe w1moninside.data;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| sid | int(10) unsigned | NO | PRI | NULL | |
| cid | int(10) unsigned | NO | PRI | NULL | |
| data_payload | text | YES | | NULL | |
+--------------+------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
Insert into week1.TableName (column list)
select column list from w1moninside.TableName where...
union
select column list from w1monoutside.TableName where
Insert into week1 (column list)
select column list from dbname.w1moninside where...
union
select column list from dbname.w1monoutside where..