MySQL Query across multiple similar views - mysql

I'm trying to write a query that compounds many MySQL Views. The MySQL version I'm using is the latest that Amazon's AWS RDS service provides. These views look like:
View 1: "Count of AAA Events"
Col1: Timestamp
Col2: Count
View 2: "Count of BBB Events"
Col1: Timestamp
Col2: Count
I have a about 100 of these views.
I would like to have a query that shapes this data to look like this:
Col1: Timestamp
Col2: Count
Col3: Event Type
That means the data would look like:
2013-01-01T00:00:00Z 10 BBB
2013-01-01T00:00:00Z 10 AAA
2013-04-10T00:00:00Z 26 AAA
2013-04-10T00:05:00Z 28 AAA
The timestamps will NOT be unique, but the combination of Time + Event Type is unique.
I've tried a wide array of approaches, but nothing has given me quite what I want. Performance isn't an issue, as these are summary reports, not OLTP queries.
Any suggestions for a good way to approach this?

SELECT Col1, Col2, "AAA" AS Col3 FROM View1
UNION ALL
SELECT Col1, Col2, "BBB" AS Col3 FROM View2
UNION ALL
SELECT Col1, Col2, "CCC" AS Col3 FROM View3
UNION ALL
.
.
.
and so on.

With help from the folks above, the final results look like this:
Select * from
(
(SELECT PointInTime, (Col1+Col2+Col3) as Failures, "ApiName1" FROM Table1)
union all
(SELECT PointInTime, (Col1+Col2+Col3) as Failures, "ApiName2" FROM Table2)
order by PointInTime
) as X;
The use of the sub-query lets me shape the final column names should I need to.
That gives results that look like:
PointInTime FailedBuckets API
2013-01-01 0 ApiName1
2013-01-01 1 ApiName2
2013-01-02 0 ApiName1
2013-01-02 1 ApiName2

Related

build table from select/union

i've a relationa table build from a csv file that contains, external keys on each row.
table structure:
| id | tree/nome | tree/regioni/0 | .... | tree/regioni/n
"n" is equal to 36!!!
I have build a table "regions" from a "SELECT/DINSTICT" and I added an id on it;
now I need to build another table to extrat the "external keys" "tree/regioni/n" with the "id" of each row.
The NOT smart way that ive found to achieve this is to build the table from a SELECT/UNION of each 'tree/regioni/n':
SELECT `id`,`tree/regioni/0`
FROM `trees` WHERE 1
UNION
SELECT `id`,`tree/regioni/1`
FROM `trees` WHERE 1
[.....]
UNION
SELECT `id`,`tree/regioni/N`
FROM `trees`
WHERE 1
Your method is fine. If trees where a view, then you would have the problem of evaluating the view multiple times. Even with a table, you have to scan the table multiple times.
Assuming you do not have duplicates that you want removed, change union to union all. You can also use a cross join:
select t.id,
(case when n = 1 then `tree/regioni/0`
when n = 2 then `tree/regioni/1`
. . .
end)
from t cross join
(select 0 as n union all
select 1 as n union all
. . .
) x;
This looks more complicated but it only scans/evaluates the table expressions once.

SQL - MYSQL One query recieving set limit on different column values

Lets say i have a table with a set of different columns (offcourse),
Example :
Table
id
col1 INTEGER(1), // 0 || 1
col2 // --||--
col3 // --||--
col4 // --||--
Is it possible, in 1 query to select 4 rows where col1=1 and then select 4 rows where col2=1 and then select 4 rows where col3=1 etc etc. I think you understand what i mean.
What i have done so far is to make 4 different queries OR make one query and just do a (col1 = 1 OR col2=1 OR... etc).
This works but if i limit that result to lets say 16, then i might get 15 rows with col1=1 and maybe 1 row with col2=1 and then col3,col4 - no result.
So dear fellas; is there a way to do this in 1 query (i think not)
Select * from table where col1=1 limit 4
Union
Select * from table where col2=1 limit 4
Union
Select * from table where col3=1 limit 4
Union
Select * from table where col4=1 limit 4
This will get you one result with 16records max. If there are less then 4rows for a certin criteria, you'll get less rows. Duplicates will be removed, resulting in less then 16 rows. Not different rows.
If for a single row col1=1 and col2=1, then it might be returned twice if you use union all, but just union is slower with large datasets
I think you are looking for the UNION ALL construct. You may simply write
SELECT * FROM tab WHERE col1 = 1
UNION ALL
SELECT * FROM tab WHERE col2 = 2
UNION ALL
SELECT * FROM tab WHERE col3 = 3
and so on. Just be aware of a fact that the rows may be duplicated in the result (if they satisfy more criteria from the conditions).

How to perform union operation between two tables?

After performing union operator between two tables in which the columns in one of the table are empty the result is displaying from second row... i dont why why is this happening ...? can anyone clarify my doubt?
my tables are sample1 and sample2
Both table contains Id, Empname , Location
data in table is
101 Null NUll
102 aaaa sec
data in table2 is
103 bbbb hyd
102 cccc gdv
Query:
(select EmpName,Location
from sample1)
union
(select EmpName,Location
from sample2)
Output
EMPNAME LOCATION
aaaa sec
bbbb hyd
cccc gdv
To remove the null records from the result, try this:
(select EmpName,Location
from sample1
WHERE EmpName IS NOT NULL
AND Location IS NOT NULL)
union
(select EmpName,Location
from sample2
WHERE EmpName IS NOT NULL
AND Location IS NOT NULL)
Result:
EMPNAME LOCATION
vijay ngdv
suresh hyd
ajay hyd
See result in SQL Fiddle.
EDIT:
I guess the record contains empty string or white spaces instead of null. So try this:
(select EmpName,Location
from sample1
WHERE LENGTH(TRIM(EmpName)) >0
AND LENGTH(TRIM(Location)) >0)
union
(select EmpName,Location
from sample2
WHERE LENGTH(TRIM(EmpName)) >0
AND LENGTH(TRIM(Location)) >0)
See result in SQL Fiddle.
Explanation:
LENGTH(TRIM(EmpName)) will return the length of the field EmpName after removing white spaces from it.
How to perform union operation between two tables?
you have to use union operator with following circumstances,
1.You have similar information in multiple tables and you want to retrieve rows from all of
them at once.
2.You want to select several sets of rows from the same table, but the conditions that
characterize each set aren't easy to write as a single WHERE clause. UNION allows retrieval
of each set with a simpler WHERE clause in its own SELECT statement; the rows retrieved by
each are combined and produced as the final query result.
Note : its not the perfect answer for your question but it helps in understanding of union
operator
please see this http://www.mysqlfaqs.net/mysql-faqs/Funtions-and-Operators/How-does-union-work-in-MySQL

sql query with sum or column

I have a table color_balls entries as below
=====================================================
Name Red_Ball Green_Ball Yellow_Ball
=====================================================
John 27 56 66
Mathew 37 45 15
=====================================================
I want to write a sql or mysql query to get the output as below.
=====================================
Color_of_Balls No_of_balls
=====================================
Red_Ball 64
Green_Ball 101
Yellow_Ball 81
=====================================
This type of query is called UNPIVOT, which unfortunately isn't natively supported by MySQL. However, you can simulate this using UNION:
SELECT 'Red_Ball' AS Color_of_Balls, SUM(Red_Ball) as No_of_Balls
FROM color_balls
UNION ALL
SELECT 'Green_Ball', SUM(Green_Ball)
FROM color_balls
UNION ALL
SELECT 'Yellow_Ball', SUM(Yellow_Ball)
FROM color_balls
Oracle10g doesn't support this natively either, although there is this workaround.
This should work in both Oracle and MySQL:
SELECT b.Color_of_Balls
, CASE b.Color_of_Balls
WHEN 'Red_Ball' THEN d.sum_red_ball
WHEN 'Green_Ball' THEN d.sum_green_ball
WHEN 'Yellow_Ball' THEN d.sum_yellow_ball
END AS No_of_balls
FROM ( SELECT 'Red_Ball' AS Color_of_Balls FROM DUAL
UNION ALL SELECT 'Green_Ball' FROM DUAL
UNION ALL SELECT 'Yellow_Ball' FROM DUAL
) b
CROSS
JOIN ( SELECT SUM(c.Red_Ball) AS sum_red_ball
, SUM(c.Green_Ball) AS sum_green_ball
, SUM(c.Yellow_Ball) AS sum_yellow_ball
FROM color_balls c
) d
ORDER
BY CASE b.Color_of_Balls
WHEN 'Red_Ball' THEN 1
WHEN 'Green_Ball' THEN 2
WHEN 'Yellow_Ball' THEN 3
END
Note that this approach requires only one pass through the color_balls table, rather than three separate passes through the table (or more, depending on how many rows you need returned.)

How to select several hardcoded SQL rows?

If you execute this query
SELECT 'test-a1' AS name1, 'test-a2' AS name2
the result will be a one row-selection with two columns having these values:
test-a1, test-a2
How can I modify the above query to have a selection with several rows, e.g.
test-a1, test-a2
test-b1, test-b2
test-c1, test-c2
I know how to do this with UNION but I feel that there exists a more simple way to do it.
PS. Sorry for such a basic question, it is very hard to google it.
Values keyword can be used as below.
select * from
(values ('test-a1', 'test-a2'), ('test-b1', 'test-b2'), ('test-c1', 'test-c2')) x(col1, col2)
The following will work for SQL:
SELECT 'test-a1' AS name1, 'test-a2' AS name2
UNION ALL
SELECT 'test-b1', 'test-b2'
UNION ALL
SELECT 'test-c1', 'test-c2'
UNION ALL is the best bet. It's faster than UNION and you will have mutually exclusive rows.
Extending the answer of #openshac for oracle, as the below mentioned code works for oracle:
SELECT 'test-a1' AS name1, 'test-a2' AS name2 from dual
UNION ALL
SELECT 'test-b1', 'test-b2' from dual
UNION ALL
SELECT 'test-c1', 'test-c2' from dual
You can use a temp table, fill it up with your results and then select from it
create table #tmpAAA (name1 varchar(10), name2 varchar(10))
insert into #tmpAAA (name1, name2)
values ('test_a', 'test_b'),
('test_c', 'test_d'),
('test_e', 'test_f'),
('test_g', 'test_h'),
('test_i', 'test_j');
select * from #tmpAAA;
This will return
name1 name2
==================
test_a test_b
test_c test_d
test_e test_f
test_g test_h
test_i test_j
I'd love to hear is anyone has a better solution. In the past I've used this:
Select top 3 'Hardcode'
from tableWithLotsOfRows
Would you mind switching abc, with 123?
select top 3
'test-A'+convert(varchar, row_number() over (order by PrimaryKey)),
'test-B'+convert(varchar, row_number() over (order by PrimaryKey))
from tableWithLotsOfRows
that should return something like:
TestA1, Test-B1
TestA2, Test-B2
TestA3, Test-B3
As of MySQL 8.0.19, it is possible to do
SELECT
column_0 AS name1,
column_1 AS name2
FROM
(VALUES
ROW('test-a1','test-a2'),
ROW('test-b1','test-b2'),
ROW('test-c1','test-c2')
) AS hardcodedNames
Which returns
name1 name2
==================
test-a1 test-a2
test-b1 test-b2
test-c1 test-c2
A note on column names
The columns of the table output from VALUES have the implicitly named columns column_0, column_1, column_2, and so on, always beginning with 0.
Documentation here: https://dev.mysql.com/doc/refman/8.0/en/values.html.
The following code work for me in MSSQL environment:
SELECT Name1,Name2 FROM(VALUES ('test-a1', 'test-a2'),
('test-b1', 'test-b2'),
('test-c1', 'test-c2'))AS Test(Name1,Name2)
Output:
Name1 Name2
------- -------
test-a1 test-a2
test-b1 test-b2
test-c1 test-c2
In MySQL you could use UNION like this:
SELECT * from
(SELECT 2006 AS year UNION
SELECT 2007 AS year UNION
SELECT 2008 AS year UNION
) AS years