MYSQL - ORDER BY clause - mysql

I have some records like this
id name sequence
------------------------
1 steve 3
2 lee 2
3 lisa 1
4 john 0
5 smith 0
I want to display records like following
id name
------------
1 lisa
2 lee
3 steve
4 john
5 smith
When i am using order by clause then it display like
name
----
john
smith
lisa
lee
steve
Query
SELECT name from tbl1 where 1 ORDER BY sequence ASC

SELECT name
FROM tbl1
ORDER BY sequence = 0,
sequence ASC
or
SELECT name
FROM tbl1
ORDER BY case when sequence <> 0 then 1 else 2 end,
sequence ASC

You can use query with if condition in ORDER BY clause
SELECT
name
from tbl1
ORDER BY IF(sequence = 0,name,sequence) ASC
Fiddle
Output
| NAME |
|-------|
| lisa |
| lee |
| steve |
| john |
| smith |

Related

How we get multiple column count(TOP) using MySQL single query?

I have a table structure like:
id | ex_name | att_name
10 | David | sam G&G
12 | John | mark hol
13 | John | john b
14 | Mark | john c
15 | David | mark hol
16 | David | mark hol
17 | Mark | sam G&G
18 | John | john b
19 | David | sam G&G
20 | John | sam G&G
When I'm using below query:
SELECT att_name
, count(att_name) as att_count
FROM `tablename`
group
by att_name
order
by att_count desc
Returns:
sam G&G = 4
mark hol = 3
john b = 2
john c = 1
I want top values of output i.e
sam G&G which is 4
Same with column ex_name it returns:
David = 4
john = 4
mark = 2
I want top values of the ex_name column which is David and John having count 4
What I want the final output like :
ex_name | att_name | ex_count | att_count
David Sam G&G 4 4
John 4
I'm also tried below query to fetch the output but in this case, I get ex_name and att_name is NULL.
SELECT a.att_name,b.att_name,max(a.ex_count),max(b.att_count)
FROM application_data
INNER JOIN (
SELECT ex_name,count(ex_name) as ex_count
FROM application_data
GROUP BY ex_name
) a
INNER JOIN (
SELECT att_name ,count(att_name) as att_count
FROM application_data
GROUP BY att_count
) b
It returns:
ex_name | att_name | ex_count | att_count
NULL NULL 4 4
Can you help me out?Thanks in advance
It appears that you want to aggregate your table by some column, and then retain all group records which share the highest count. One way to do this is to add a HAVING clause to your current query which asserts that the count for a group to be retained is the highest count from all groups.
SELECT att_name, COUNT(*) AS cnt
FROM tablename
GROUP BY att_name
HAVING COUNT(*) = (SELECT COUNT(*) FROM tablename
GROUP BY att_name ORDER BY COUNT(*) DESC LIMIT 1);
Demo

MySQL assigning value to a null alias

results table:
result_event | name | position
-------------+---------------+------------
1 | Jason Smith | 1
1 | David Johnson | 2
1 | Randy White | 3
1 | Billy Hansen | 4
2 | Wally Mann | 1
2 | Jason Smith | 2
2 | Billy Hansen | 3
2 | David Johnson | 4
2 | Randy White | 5
I have a table with race results as above. I want to sort the riders by their combined placement in the two races. (eg 1st plus 2nd = 3, 2nd plus 4th = 6, etc.) Racer "Wally Mann" did not race the first race so even though he won the second race, he should be scored behind all others.
Desired Result:
Name | Race1 | Race2
--------------+--------+-------
Jason Smith | 1 | 2
David Johnson | 2 | 4
Billy Hansen | 4 | 3
Randy White | 3 | 5
Wally Mann | NULL | 1
Current query:
SELECT name,
CASE(WHEN result_event=1 then position else 0 END) Race1,
CASE(WHEN result_event=2 then position else 0 END) Race2,
SUM(position) eventscore
FROM results
GROUP BY name
ORDER BY eventscore DESC
In my current query, "Wally Mann" is first in the list because (Null + 1) < (1+2). What can I do to make the (Null + 1) result sort AFTER all the racers who have two results?
Change your ORDER BY to sort by number of records DESC and THEN BY eventscore
ORDER BY count(*) DESC, eventscore ASC
select name from results
group by name
order count(*) desc, sum(position);

mysql Update table after querying from it

I have a table filled with first and last names. I have two other columns that I am trying to update. These two columns has the number of people that have the same first names and same last names. For example,
first last samef samel
John Smith 1 2
John Adams 1 1
Mary Kate 0 0
Kate Adams 2 1
Kate Smith 2 2
Kate Smith 2 2
Alice Mirth 0 0
So far I can only come up with these two queries, but of course they are not correct. They return the total count for each name when I need the total count - 1. Plus, the results are shown on separate tables.
I was wondering if I should use a stored procedure where I use variables to store the count for samef and samel. And then insert it into the names table, but I don't know the correct syntax for this.
SELECT first, last,
( SELECT COUNT(*) FROM names WHERE first = table1.first) AS samef
FROM names AS table1
SELECT first, last,
( SELECT COUNT(*) FROM names WHERE last = table2.last) AS samel
FROM names AS table2
I am new to mySQL so please provide explanations.
Just like Strawberry mentioned, do not store information that can be derived. Databases are great at storing data optimally. SQL is great at extracting table and derived/calculated data. Try this:
select `first`, `last`,
(select count(*)-1 from test where `first` = t.`first`) as samef,
(select count(*)-1 from test where `last` = t.`last`) as samef
from test t;
Example: http://sqlfiddle.com/#!9/9c673f/1
Result:
| first | last | samef | samef |
|-------|-------|-------|-------|
| john | smith | 1 | 2 |
| john | adams | 1 | 1 |
| mary | kate | 0 | 0 |
| kate | adams | 2 | 1 |
| kate | smith | 2 | 2 |
| kate | smith | 2 | 2 |
| alice | mirth | 0 | 0 |

get sum for multiple blocks

I have a table like this:
name | day | score
------------------
John | 1 | 4
John | 2 | 5
John | 3 | 6
Marc | 1 | 7
Marc | 2 | 4
Marc | 3 | 5
Paul | 1 | 8
Paul | 2 | 2
Paul | 3 | 3
I want to get the sum of the score for each person, but only for certain days, sorted by this sum. let's say I want to get the score-sum of the 1. and 2. day, this is what I expect:
name | sum(score)
-----------------
Marc | 11
Paul | 10
John | 9
this is what failed:
SELECT name, sum(score) FROM mytable WHERE day<=2
I think I have to surround the sum(score)-part with some IF-statement, but I have no idea how.
Just add group by
SELECT name, sum(score) FROM mytable WHERE day<=2 group by name
Use sum function and group by clause for grouping the result.
query
select name,sum(score) as score
from myTable
where day in (1,2)
group by name
order by sum(score) desc;
fiddle demo

SQL - select a list of lists

So I have a table where each row may or may not be merged via a merge_id.
Its easy to jump in and grab all merged rows, where the merge_id column is not null. The thing is I want to output the merged rows together in one container on the client side.
I there any way for sql to return a collection for merged collections ?
Do I sort in ascending order of the merge ID and trust that its sequential ?
EDIT
________________________________________________
|id | firstname | lastName | merge_id |
|------------------------------------------------|
| 1 | jane | Doe | 1 |
-------------------------------------------------|
|------------------------------------------------|
| 2 | John | Doe | 1 |
-------------------------------------------------|
|------------------------------------------------|
| 3 | max | payne | 2 |
-------------------------------------------------|
|------------------------------------------------|
| 4 | sub | zero | 3 |
--------------------------------------------------
So I want to query in such a way that I know that jane and max belong to different mergers.
How about
SELECT firstname, lastname, merge_id
FROM table t
ORDER BY t.merge_id
That would give you a record per person, and the merge_id will be ascending:
1 | Jane Doe
1 | John Doe
2 | max payne
3 | sub zero
Otherwise, you can use GROUP_CONCAT:
SELECT merge_id , GROUP_CONCAT(CONCAT(firstname, ' ', lastname))
FROM table t
GROUP BY t.merge_id
ORDER BY t.merge_id
Which will give one record per merge_id:
1 | Jane Doe, John Doe
2 | max payne
3 | sub zero