What is the easiest way to select data from two tables and rather than join them, have them appear as separate rows. Both tables have similar or matching fields and I want to run some aggregate function on them such as avg all the rows that occurred in the same month, from both tables.
for example I have two tables, one that is shows transactions from one system and another with transactions from a different system. Is there a way to grab all the transactions from both tables as separate rows? if table 1 had twenty records and table 2 have thirty records, I'd like there to be 50 rows on the return.
You could try something like this:
SELECT ...
FROM (
SELECT f1,f2,f3 FROM table1
UNION
SELECT f1,f2,f3 FROM table2
)
WHERE ...
You could try this notattion:
SELECT * from table1,table2
More complicated one :
SELECT table1.field1,table1.field2, table2.field3,table2.field8 from table1,table2 where table1.field2 = something and table2.field3 = somethingelse
Such queries are usually called "implicit JOINs" and Explicit vs implicit SQL joins asks how both compare. In some cases implicit query execution planning is identical to explicit JOINs.
The UNION ALL operator may be what you are looking for.
With this operator, you can concatenate the resultsets from multiple queries together, preserving all of the rows from each. Note that a UNION operator (without the ALL keyword) will eliminate any "duplicate" rows which exist in the resultset. The UNION ALL operator preserves all of the rows from each query (and will likely perform better since it doesn't have the overhead of performing the duplicate check and removal operation).
The number of columns and data type of each column must match in each of the queries. If one of the queries has more columns than the other, we sometimes include dummy expressions in the other query to make the columns and datatypes "match". Often, it's helpful to include an expression (an extra column) in the SELECT list of each query that returns a literal, to reveal which of the queries was the "source" of the row.
SELECT 'q1' AS source, a, b, c, d FROM t1 WHERE ...
UNION ALL
SELECT 'q2', t2.fee, t2.fi, t2.fo, 'fum' FROM t2 JOIN t3 ON ...
UNION ALL
SELECT 'q3', '1', '2', buckle, my_shoe FROM t4
You can wrap a query like this in a set of parenthesis, and use it as an inline view (or "derived table", in MySQL lingo), so that you can perform aggregate operations on all of the rows.
SELECT t.a
, SUM(t.b)
, AVG(t.c)
FROM (
SELECT 'q1' AS source, a, b, c, d FROM t1
UNION ALL
SELECT 'q2', t2.fee, t2.fi, t2.fo, 'fum' FROM t2
) t
GROUP BY t.a
ORDER BY t.a
If your question was this -- Select ename, dname FROM emp, dept without using joins..
Then, I would do this...
SELECT ename, (SELECT dname
FROM dept
WHERE dept.deptno=emp.deptno)dname
FROM EMP
Output:
ENAME DNAME
---------- --------------
SMITH RESEARCH
ALLEN SALES
WARD SALES
JONES RESEARCH
MARTIN SALES
BLAKE SALES
CLARK ACCOUNTING
SCOTT RESEARCH
KING ACCOUNTING
TURNER SALES
ADAMS RESEARCH
ENAME DNAME
---------- --------------
JAMES SALES
FORD RESEARCH
MILLER ACCOUNTING
14 rows selected.
You should try this
SELECT t1.*,t2.* FROM t1,t2
SELECT * from table1
UNION
SELECT * FROM table2
Union will fetch data by row not column,So If your are like me who is looking for fetching column data from two different table with no relation and without join.
In my case I am fetching state name and country name by id. Instead of writing two query you can do this way.
select
(
select s.state_name from state s where s.state_id=3
) statename,
(
select c.description from country c where c.id=5
) countryname
from dual;
where dual is a dummy table with single column--anything just require table to view
select 'test', (select name from employee where id=1) as name, (select name from address where id=2) as address ;
In this case we are assuming that we have two tables:
SMPPMsgLogand SMSService with common column serviceid:
SELECT sp.SMS,ss.CMD
FROM vas.SMPPMsgLog AS sp,vas.SMSService AS ss
WHERE sp.serviceid=5431
AND ss.ServiceID = 5431
AND Receiver ="232700000"
AND date(TimeStamp) <='2013-08-07'
AND date(TimeStamp) >='2013-08-06' \G;
you can try this works always for me
query="SELECT * from tableX,tableY,table8";
Related
How can I create a query to SELECT ALL DB WITHOUT duplicates
Like (old DB that is no longer in use c,f,g. basically if it does have eur and has an original name than it is relevant):
a
b
c
ceur
d
f
feur
g
geur
I need it to be like:
a
b
ceur
d
feur
geur
Many thanks...
SELECT DISTINCT
is what you're looking for. See more here.
For instance, let's say you have a table that contains the following rows:
name, city, address, country.
You now wish to get the countries that has been stored, without duplicates. Multiple people might come from the same country, and so the table would most likely have duplicate entries of that country.
How you achieve this is by using the SELECT DISTINCT.
Example:
SELECT DISTINCT country FROM table_name;
What this will do is retreive the country row without duplicates. That way, you can see which countries are actually stored in that table without duplicates.
If you have multiple databases (I don't know if that's what you were getting at), then you will need to perform a JOIN on the relevant tables, given you have access to them all. I would recommend doing a LEFT JOIN if you are to join more than just 1 extra table.
Example:
SELECT DISTINCT table_name.row_name, table_name.row_name2, table_name.row_name3
FROM table_name
LEFT JOIN table_name2 ON table_name.row_name = table_name2.row_name
LEFT JOIN table_name3 ON table_name2.row_name = table_name3.row_name
[...]
WHERE table.row_name = 'value';
Can you query information_schema.TABLES and distinct in the select, plus a predicate to filter out whatever you don't want?
You can do:
select t.*
from t
where name like '%eur'
union all
select t.*
from t
where not like '%eur' and
not exists (select 1 from t t2 where t2.name = concat(t.name, 'eur');
I have a table that looks like this,
year,t1,t2,winner
I want to find the total appearances in the finals for a team, basically I need to union these two queries
select t1 from cups
union
select t2 from cups
and then do a group by. However, I would like to run this query without using UNION(not a homework) as I believe UNION is not standard SQL. I can't use IN as I will lose the counts. Does anybody have any suggestions?
You need to get two rows for each input row, one for t1 and one for t2. UNION is the proper and standard SQL way to do that. I can't even think of another vaguely sensible way to do it, and even those appear to scan the table twice.
You should use UNION ALL to include even the duplicates also.
Then count each team.
Query
select t.team,count(t.team) as `Total Appearances`
from
(
select team1 as team from tblMatches
union all
select team2 as team from tblMatches
)t
group by t.team;
SQL Fiddle
UNION Operator is reserved keyword in SQL
About SQL UNION Operator
The UNION operator is used to combine the result-set of two or more SELECT statements.
Notice that each SELECT statement within the UNION must have the same number of columns. The columns must also have similar data types. Also, the columns in each SELECT statement must be in the same order.
SQL UNION Syntax
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
Same with Inner join
select t1
FROM cups
INNER JOIN cups2
ON t1.column_name=t2.column_name;
and you are finding two different fields in same table
select t1 from cups
union
select t2 from cups
so try this
SELECT *
FROM cups
WHERE t1=t2
If you are looking to find the team name and count of how many times that team has reached finals, something like this might be of help :
select team, count(1) as appearances from
( select t1 as team from cups
union all
select t2 as team from cups
) as totalAppearances
group by team
How can i perform these two queries in one single query, so that it shows the eid that has more than 2 values and shows its eid as well?
select eid, count(Edited_by.eid)
from Edited_by
group by eid;
select Editor.eid
from Editor
where ( select count(*)
from Edited_by
where Edited_by.eid=Editor.eid ) > 2;
UPDATE
A predicate in the HAVING clause can operate on aggregate expressions. I think you may be looking for something like this:
SELECT t.eid
, COUNT(t.eid) AS cnt
FROM Edited_by t
GROUP BY t.eid
HAVING COUNT(t.eid) > 2
Whoops. I entirely missed that the two queries were referencing two different tables.
To also reference the Editor table, you could use the query above as an inline view.
SELECT c.eid AS edited_by_eid
, c.cnt AS cnt
, IF(c.cnt>2,e.Eid,NULL) AS editor_eid
FROM Editor e
JOIN ( SELECT t.eid
, COUNT(t.eid) AS cnt
FROM Edited_by t
GROUP BY t.eid
) c
ON c.eid = e.Eid
FOLLOWUP
Q: "I want to get the result of BOTH queries by running one."
A: I'm not understanding exactly what you want to achieve.
To have two separate resultsets returned, you would need to run two separate statements. MySQL can return multiple resultsets from a stored procedure, for example, a procedure could execute the two queries. The client could process both resultsets (if that's supported and enabled in the client interface library.) That would be a "single statement" (CALL my_procedure;).
If you want to concatenate the results of two separate queries, you could use the UNION ALL set operator. Normally, I would return a discriminator column to distinguish which rows were returned by which query. To do that, the number of columns and the datatypes of each column must match between the two queries.
In the example you give, the query from the Editor table would need to return a dummy integer-type column in order to concatenate the two results.
SELECT t.eid
, COUNT(Edited_by.eid) AS cnt
FROM Edited_by t
GROUP BY t.eid
UNION ALL
SELECT e.eid
, 0 AS cnt
FROM Editor e
WHERE ( SELECT COUNT(*)
FROM Edited_by c
WHERE c.eid=e.eid
) > 2
I have the following table:
CREATE TABLE sometable (my_id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING, number STRING);
Running this query:
SELECT * FROM sometable;
Produces the following output:
1|someone|111
2|someone|222
3|monster|333
Along with these three fields I would also like to include a count representing the amount of times the same name exists in the table.
I've obviously tried:
SELECT my_id, name, count(name) FROM sometable GROUP BY name;
though that will not give me an individual result row for every record.
Ideally I would have the following output:
1|someone|111|2
2|someone|222|2
3|monster|333|1
Where the 4th column represents the amount of time this number exists.
Thanks for any help.
You can do this with a correlated subquery in the select clause:
Select st.*,
(SELECT count(*) from sometable st2 where st.name = st2.name) as NameCount
from sometable st;
You can also write this as a join to an aggregated subquery:
select st.*, stn.NameCount
from sometable st join
(select name, count(*) as NameCount
from sometable
group by name
) stn
on st.name = stn.name;
EDIT:
As for performance, the best way to find out is to try both and time them. The correlated subquery will work best when there is an index on sometable(name). Although aggregation is reputed to be slow in MySQL, sometimes this type of query gets surprisingly good results. The best answer is to test.
Select *, (SELECT count(my_id) from sometable) as total from sometable
I have a list of ids and need to check whether user with id is in DB or not in one SELECT. Like SELECT WHERE IN (). But SELECT WHERE IN () doesn't suit my needs, I need in one SELECT distinguish those ids that are in table, and those that are not, not using any loops like multiple SELECTS. Any ideas are welcome!
I'm not sure if this is what you need, but I guess you have table 1 which contains a lot of IDs, and you would like to see which ones occur in table 2 and which ones don't?
select T1.ID, count(*) 'Times of occurrences in T2'
from table 1 T1
left outer join table 2 T2
ON T1.ID = T2.ID
group by T1.ID
You should provide more details. Would it be a single query so a list could be hardcoded into query or you want to find general solution for any list of ids provided? How long is your list?
For single query and not very long list you can use union. On example:
SELECT some_value, EXISTS( SELECT 1 FROM tableName WHERE user_id = some_value )
UNION ALL
SELECT other_value, EXISTS( SELECT 1 FROM tableName WHERE user_id = other_value )
UNION ALL
SELECT other_value2, EXISTS( SELECT 1 FROM tableName WHERE user_id = other_value2 )
UNION ALL
.....
If your list of ids can vary and/or consists of thousands of records it is impossible. In list you have columnar layout and you want to change it to row-level results. In MsSQL there are PIVOT, UNPIVOT clauses which can do that. In MySQL such transformation without explicit unions are impossible.