The issue here is suppose if i want to use two queries seperated by UNION, the query is as
$query=(select a.name,a.age,b.country,b.state from a,b where a.aid=b.bid) UNION (select a.name,a.age,c.profession,c.salary from a,c where a.anid=c.cid)
here the result would only show the first query's result , Any way in which i could display the result of 2nd query also down to the result of first query using UNION. Expecting any help on this. Thanks
Are you after
(
select a.name,a.age,b.country,b.state,null as profession,null as salary
from a,b
where a.aid=b.bid
)
UNION
(
select a.name,a.age,null,null,c.profession,c.salary
from a,c
where a.anid=c.cid
)
You will have null in the profession and salary columns from the first query and null in country and state columns in the second query
Try this
$query=(select a.name,a.age,b.country,b.state from a,b where a.aid=b.bid UNION select a.name,a.age,c.profession,c.salary from a,c where a.anid=c.cid)
by the way the fields in both select must be the same datatype
As I understood it a union was to do the same query on two different tables. If you get a result from the first half of the union you will not get the results from the second half.
Basic property of UNION is
Selected columns listed in
corresponding positions of each SELECT
statement should have the same data
type. (For example, the first column
selected by the first statement should
have the same type as the first column
selected by the other statements.)
If the data types of corresponding
SELECT columns do not match, the types
and lengths of the columns in the
UNION result take into account the
values retrieved by all of the SELECT
statements. For example, consider the
following:
Related
I have been trying but it seems I am missing something. I want to combine two results from two tables by a common field.
I would like to group results from these two queries by customer field.
SELECT errors.customer, count(errors.customer) as err_count,severity from errors group by customer,severity;
SELECT customer,sum(size) as Tot_size,count(customer) as Policy_count from backup group by customer;
I have tried this.
SELECT errors.customer, count(errors.customer) as err_count,severity from errors group by customer,severity union all SELECT customer,count(customer) as Policy_count ,sum(size) as Tot_size from backup group by customer;
But for some reason some columns are missing.
You should follow the requirements for union:
The UNION operator is used to combine the result-set of two or more SELECT statements.
Each SELECT statement within UNION must have the same number of columns
The columns must also have similar data types
The columns in each SELECT statement must also be in the same order
Apparently, the above items are not satisfied in your query.
Try something like this:
SELECT q1.customer, Tot_size, Policy_count, err_count, severity
FROM ( SELECT customer, SUM(size) AS Tot_size, COUNT(customer) AS Policy_count
FROM backup GROUP BY customer ) q1
LEFT JOIN ( SELECT customer, COUNT(customer) AS err_count, severity
FROM errors GROUP BY customer, severity ) q2 ON q1.costumer = q2.costumer
Your first query contains three columns and your second one contains two columns.
In order to use the UNION operator your two queries need to have the same amount of columns, and the columns should be compatible.
In your case the second query lacks a third column. If there is no corresponding column to use you can set a default such as
"'n/a' as severity "
if it should be textual or
"0 as severity "
for a numerical value.
Cheers Martin
I have created a query that gets two values. It outputs the correct values but now i want to add these values together to get one value in a column named "Total Cost". Is this possible if "Total Cost" is not a column in my tables?
Here is the query i used:
SELECT ROUND(SUM(drugcost_cost),0) FROM drugcost UNION SELECT ROUND(SUM(operation_cost),0) FROM operation
Do this with subqueries:
SELECT d.dcost, o.ocost, (d.dcost + o.ocost) as totalcost
FROM (SELECT ROUND(SUM(drugcost_cost),0) as dcost FROM drugcost) d CROSS JOIN
(SELECT ROUND(SUM(operation_cost),0) as ocost FROM operation) o;
By the way, your query is an excellent example of why you should always use union all unless you really know why you want union instead. If the values from the two subqueries are the same, then union will remove duplicates -- and you will get only one row.
Say I have this table with two columns. Both columns contain IP-addresses. I want a SELECTquery that gets me a list of all ip-addresses that occur in either the first column, or the second column, or both. Just a list of all distinct ip-addresses in that table. How is that done? I would have thought that SELECT DISTINCT ip_src, ip_dst FROM table would have done the trick.
Note that your example only applies the distinct to ip_src. To get just one column try a UNION:
SELECT ip_src FROM table
UNION
SELECT ip_dst FROM table
As noted in the comments not only will the UNION remove duplicates between the columns but also those that occur with the columns meaning using a DISTINCT is unnecessary.
I need help with CONCAT function. I have two select queries and the result of every query is one column. I need to merge this two columns in one. Is that possible? Beacuse, I can't get result even if I try with simple select queries like:
SELECT owner FROM table WHERE number="value1";
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
These queries work and throw 3 rows like result. But, if I want to merge them in one column using CONCAT - that doesn't work. Do you know why?
SELECT CONCAT(SELECT owner FROM table WHERE number="value1",
SELECT number FROM table WHERE owner="value2" AND number IS NOT null
) as NEW_COLUMN FROM table;
I think you want this:
SELECT CONCAT(owner, number) newCol1
FROM yourTable
WHERE number="value1"
OR (owner="value2" AND number IS NOT null)
SELECT
CONCAT(owner, number) as NEW_COLUMN
FROM
table
WHERE
owner = "value2"
AND number = "value1"
AND number IS NOT NULL
The fundamental reason is that the DB cannot concatenate two different SELECTs which might have a different number of rows.
What you need to do is to re-formulate your query in terms of a JOIN.
For example suppose we have this table:
owner number
John value1
value2 123456
Your first query:
SELECT owner FROM table WHERE number="value1";
will return "John". The second one
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
will return "123456".
If you CONCAT the two values you would therefore get "John 123456".
First of all, is this the expected behaviour of the query you want? What happens is there is a third row with owner=Jack and number=value1, so that the first query returns TWO rows "John" and "Jack"?
One thing you could look into is the CROSS JOIN syntax.
SELECT CONCAT (table1.owner, ', ', table2.number) AS new_column
FROM ( SELECT owner FROM table WHERE number="value1" ) AS tablel1
CROSS JOIN
(SELECT number FROM table WHERE owner="value2" AND number IS NOT null ) AS table2;
Note that if the first query returns three rows and the second four rows, the combined query will return 3*4 = 12 rows.
I have two tables.
I query like this:
SELECT * FROM (
Select requester_name,receiver_name from poem_authors_follow_requests as one
UNION
Select requester_name,receiver_name from poem_authors_friend_requests as two
) as u
where (LOWER(requester_name)=LOWER('user1') or LOWER(receiver_name)=LOWER('user1'))
I am using UNION because i want to get distinct values for each user if a user exists in the first table and in the second.
For example:
table1
nameofuser
peter
table2
nameofuser
peter
if peter is on either table i should get the name one time because it exists on both tables.
Still i get one row from first table and a second from table number two. What is wrong?
Any help appreciated.
There are two problems with your SQL:
(THis is not the question, but should be considered) by using WHERE over the UNION instead of the tables, you create a performance nightmare: MySQL will create a temporary table containing the UNION, then query it over the WHERE. Using a calculation on a field (LOWER(requester_name)) makes this even worse.
The reason you get two rows is, that UNION DISTINCT will only suppress real duplicates, so the tuple (someuser,peter) and the tuple (someotheruser, peter) will result in duplication.
Edit
To make (someuser, peter) a duplicate of (peter, someuser) you could use:
SELECT
IF(requester_name='peter', receiver_name, requester_name) AS otheruser
FROM
...
UNION
SELECT
IF(requester_name='peter', receiver_name, requester_name) AS otheruser
FROM
...
So you only select someuser which you already know : peter
You need the where clause on both selects:
select requester_name, receiver_name
from poem_authors_follow_requests
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1')
union
select requester_name, receiver_name
from poem_authors_friend_requests
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1')
The two queries are independent of each other, so you shouldn't try to connect them other than by union.
You can use UNION if you want to select rows one after the other from several tables or several sets of rows from a single table all as a single result set.
UNION is available as of MySQL 4.0. This section illustrates how to use it.
Suppose you have two tables that list prospective and actual customers, a third that lists vendors from whom you purchase supplies, and you want to create a single mailing list by merging names and addresses from all three tables. UNION provides a way to do this. Assume the three tables have the following contents:
http://w3webtutorial.blogspot.com/2013/11/union-in-mysql.html
You are doing the union before and then applying the where clause. So you would get a unique combination of "requester_name,receiver_name" and then the where clause would apply. Apply the where clause in each select...
Select requester_name,receiver_name from poem_authors_follow_requests
where (LOWER(requester_name)=LOWER('user1')
or LOWER(receiver_name)=LOWER('user1'))
UNION
Select requester_name,receiver_name from poem_authors_friend_requests
where (LOWER(requester_name)=LOWER('user1')
or LOWER(receiver_name)=LOWER('user1'))
In your where statement, reference the alias "u" for each field refence in your where statement.
So the beginning of your where statement would be like: where (LOWER(u.requester_name) = ...
This is simlar to the answer you can see in: WHERE statement after a UNION in SQL?
You should be able to use the INTERSECT keyword instead of doing a nested query on a UNION.
SELECT member_id, name FROM a
INTERSECT
SELECT member_id, name FROM b
can simply be rewritten to
SELECT a.member_id, a.name
FROM a INNER JOIN b
USING (member_id, name)
http://www.bitbybit.dk/carsten/blog/?p=71