SQL Query containing 2 result sets - mysql

select name from persons where gender = 'male' order by name limit 10
select name from persons where gender = 'female' order by name limit 10
How can I get the first 10 males and the first 10 females in a single result set (20 entries) with a single SQL query call? Is this possible?

The correct syntax uses parentheses and union all:
(select name
from persons
where gender = 'male'
order by name
limit 10
) union all
(select name
from persons
where gender = 'female'
order by name
limit 10
)

It is possible and it's called UNION

You can use UNION Operator.
UNION is used to combine the result from multiple SELECT statements
into a single result set.
select name from persons where gender = 'male' order by name limit 10
UNION
select name from persons where gender = 'female' order by name limit 10

SELECT name FROM persons WHERE gender = 'male' ORDER BY name LIMIT 0,10 ;
UNION
SELECT name FROM persons WHERE gender = 'female' ORDER BY name LIMIT 0,10 ;

with ROW_NUMBER()
SELECT * FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY gender ORDER BY gender) row_no,* FROM Person
) A WHERE A.row_no <= 10

Related

MySQL: Conditional Order By

I have a column called first_name in my 'employee' table.
I would like to select & order those names by DESC if COUNT(first_name) is an odd number or select & order those names by ASC if COUNT(first_name) is an even number.
Something like that is written below
SELECT first_name
FROM employee
ORDER BY (first_name DESC if COUNT (first_name) % 2 != 0 ELSE first_name ASC);
You have to force mysql to choose one option
like
SELECT first_name
FROM employee
ORDER BY (CASE WHEN CHAR_LENGTH(first_name) % 2 <> 0 THEN first_name END) ASC,
(CASE WHEN CHAR_LENGTH(first_name) % 2 = 0 THEN first_name END) DESC
It can only be one or the other.

SQL limiting the output to a number of results

I have this query.
SELECT * FROM Customer WHERE TAGID IN ('UK', 'Germany');
This outputs the results to show all customers in UK and Germany, but as you can imagine, there will be loads of outputs, and I just require it to output 2 results for UK and 2 results for Germany?
Is this possible?
UNION ALL comes to mind:
(SELECT c.*
FROM Customer c
WHERE TAGID = 'UK'
LIMIT 2
) UNION ALL
(SELECT c.*
FROM Customer c
WHERE TAGID = 'Germany'
LIMIT 2
);
Note that this can take advantage of an index onCustomer(TagID). Also, this returns two arbitrary rows. You can use an ORDER BY to return the newest, oldest, biggest, smallest, reddest, bluest or whatever.
Here is a db<>fiddle.
Yes It is possible. Please check below methods.
Method 1 :
SELECT TOP 2 * FROM Customer WHERE TAGID ='UK'
UNION ALL
SELECT TOP 2 * FROM Customer WHERE TAGID = 'Germany'
Method 2:
(SELECT * FROM Customer WHERE TAGID ='UK' LIMIT 2)
UNION ALL
(SELECT * FROM Customer WHERE TAGID = 'Germany' LIMIT 2)
Method 3:
(SELECT * FROM Customer WHERE TAGID ='UK' AND ROWNUM = 2)
UNION ALL
(SELECT * FROM Customer WHERE TAGID = 'Germany' AND ROWNUM = 2)

Get latest two distinct location from table

Below is my table,
SELECT DISTINCT(availability_location) as location FROM table_name WHERE user_id = '8' ORDER BY availability_date DESC LIMIT 2
I'm getting following result
I want following result :
2016-05-27 pune
2016-05-20 Burbank
i.e. Unique availability_location as well as latest two entries.
You have to use GROUP BY for this:
SELECT availability_location as location,
MAX(availability_date) AS max_date
FROM table_name
WHERE user_id = '8'
GROUP BY location
ORDER BY max_date DESC LIMIT 2
You can use GROUP BY and order by the max date :
SELECT t.availability_location
FROM table_name t
WHERE user_id = '8'
GROUP BY t.availability_location
ORDER BY max(s.availability_date) DESC LIMIT 2
Output :
availability_location
---------------------
pune
Burbank
EDIT: next time, you should mention that you want it to be case sensitive. You can try doing it like this:
SELECT t.availability_location
FROM table_name t
INNER JOIN(SELECT s.availability_location , max(s.availability_date) as max_d
FROM table_name s
WHERE s.user_id = '8'
GROUP BY s.availability_location) t2
ON(t2.availability_location = t.availability_location AND
t2.max_d = t.availability_date)
ORDER BY t.availability_date DESC LIMIT 2

Order mysql query in the same order I provide the OR statements in

Here's a query:
SELECT *
FROM table
WHERE id = 1
OR id = 100
OR id = 50
Note that I provided the ids in this order: 1,100,50.
I want the rows to come back in that order: 1,100,50.
Currently, i comes back 1,50,100 - basically in ascending order. Assume the rows in the table were inserted in ascending order also.
Use the MySQL specific FIND_IN_SET function:
SELECT t.*
FROM table t
WHERE t.id IN (1, 100, 50)
ORDER BY FIND_IN_SET(CAST(t.id AS VARCHAR(8)), '1,100,50')
Another way to approach this would put the list in a subquery:
select table.*
from table join
(select 1 as id, 1 as ordering union all
select 100 as id, 2 as ordering union all
select 50 as id, 3 as ordering
) list
on table.id = list.id
order by list.ordering
You can just do this with ORDER BY:
ORDER BY
id = 1 DESC, id = 100 DESC, id = 50 DESC
0 is before 1 in ORDER BY.
Try this
SELECT *
FROM new
WHERE ID =1
OR ID =100
OR ID =50
ORDER BY ID=1 DESC,ID=100 DESC,ID=50 DESC ;
http://www.sqlfiddle.com/#!2/796e2/5
... WHERE id IN (x,y,x) ORDER BY FIELD (id,x,y,z)

Mysql ORDER BY or MAX() for several table fields orderring?

I've mixed up with a strange behavior of MySQL query. I have next mysql query:
SELECT 'username','status', 'field_1', 'field_2', 'field_3', 'field_4',
FROM my_table
ORDER by field_1 DESC, field_2 DESC, field_3 DESC, field_4 DESC
LIMIT 0,10
By the idea, it has to order 10 rows in descending method depending on how many values fields have in ORDER BY condition. But in the result I get the next one:
kate 103
pete 101
steve 102
instead of
kate 103
steve 102
pete 101
Does anyone know why it set incorrect order? And what to do in order to make the proper ORDER BY DESC condition?
Is it possible to use MAX() for several fields? If yes, maybe it is possible to organize the MySQL query like this?
SELECT 'username','status', 'field_1', 'field_2', 'field_3', 'field_4', MAX(field_1,field_2,field_3,field_4) AS total
FROM my_table
ORDER by total DESC
LIMIT 0,10
You can't use MAX() because that function returns the largest value in one column over many rows. But you can use MySQL's GREATEST() function. This returns the largest of its arguments, which all come from one row.
SELECT `username`, `status`, GREATEST(field_1,field_2,field_3,field_4) AS field_greatest
FROM my_table
ORDER BY field_greatest DESC
LIMIT 0,10
But I would also comment that you have violated 1st Normal Form by storing multiple columns that should be the same "kind" of data. The consequences are that you face this troublesome query. Also you'll need to rewrite all your queries when you add a fifth field.
Instead, create a second table and store all the "fields" in a single column, with a reference to the user. Then you can join the tables:
SELECT t.username, t.status, f.field
FROM my_table AS t
LEFT OUTER JOIN (SELECT username, MAX(field) AS field FROM my_fields GROUP BY username) AS f
ON t.username = f.username
ORDER BY f.field DESC
LIMIT 0,10
Or my favorite way of getting the row with the greatest value per group:
SELECT t.username, t.status, f1.field
FROM my_table AS t
JOIN my_fields AS f1 ON t.username = f1.username
LEFT OUTER JOIN my_fields AS f2 ON t.username = f2.username AND f1.field < f2.field
WHERE f2.username IS NULL
ORDER BY f1.field DESC
LIMIT 0,10
You cannot feed multiple values into max. You can do a few nested IF()'s though.
SELECT `username`,`status`,
MAX(
if( field_1 > field_2 and field_1 > field_3 and field_1 > field_4 ,field_1,
if( field_2 > field_3 and field_2 > field_4 ,field_2,
if( field_3 > field_4, field_3, field_4 )))) AS total
FROM my_table
ORDER by total DESC
LIMIT 0,10