Append blank results to end in alphabetical order - mysql

I would like to return a list of items by alphabetical order, but have the "empty" results append to the end as opposed to appearing at the beginning. Is there a way to do this using the MySQL ORDER statement, or perhaps another way?
SELECT * FROM persons WHERE status = 'active' ORDER BY lastName;
What I get:
Jason
Peter
Frank Asimov
Reda Banks
Scott Sorrel
What I want:
Frank Asimov
Reda Banks
Scott Sorrel
Jason
Peter

SELECT * FROM persons WHERE status = 'active'
ORDER BY case when ifnull(lastName,'') = '' then 1 else 0 end, lastname

You can do it using the FIELD statement. It goes something like that:
SELECT [...] ORDER BY FIELD(lastName, '') DESC
This will either append all the empty-string lastnames to the end. If instead of empty strings, you have NULL on your database:
SELECT [...] ORDER BY FIELD(lastName, NULL) DESC;

I believe all you need is to ORDER BY the firstName:
SELECT * FROM persons WHERE status = 'active' ORDER BY lastName, firstName

Related

Selecting a specific row followed by an order by?

I have this data
names
============
All
Brian
Carey
Heather
Robert
Zach
_Immediate
This is when they are selected ORDER BY name. I would like to craft a statement so that the _Immediate appears at top like
names
============
_Immediate
All
Brian
Carey
Heather
Robert
Zach
If it matters/helps, _Immediate has the absolute lowest ID in the list. How can I do this? Is a UNION the only way?
You can specify the ORDER BY using a CASE expression:
ORDER BY CASE
WHEN names = '_Immediate' THEN 0
ELSE 1
END
, names
In MySQL, I think the simplest method is:
order by (name = '_Immediate') desc, name
MySQL treats a boolean as an integer, with "1" for true and "0" for false. The desc is so the "1" is before the "0".
You can try below -
select * from tablename
order by case when names='_Immediate' then 0 else 1 end, names

MySQL - Take Specific row being a value NULL or max, not just column

I'm searching how to make a select with 2-3 columns and take the results with the parameter in one column as NULL, otherwise if there is no NULL for a username, take the max date.
My problem is that in the results, the ipaddr is from the max stoptime row, if there is no NULL row i get the ipaddr correctly
Is important for me for can search by user.
Lets take a look to my database format:
username stoptime ipaddr
peter 2012-10-16 00:00:00 1.1.1.1
obama 2014-03-12 00:00:00 1.1.1.2
peter 2013-10-16 00:00:00 1.1.1.3
obama NULL 1.1.1.4
When i launch:
SELECT username,case when MAX(stoptime is NULL)=0 then max(stoptime) end as stoptime,ipaddr
FROM tb
WHERE username LIKE "%OBAM%" group by username;
In this example i expect to take from my query this results:
obama NULL 1.1.1.4
Instead this i take this:
obama NULL 1.1.1.2
Thanks!
You are using group by incorrectly. In particular, you have columns in the select that are not in the group by. MySQL specifically discourages this (see here).
The simplest way to do what you want is:
SELECT username,
(case when max(stoptime is null) = 0
then max(stoptime)
end) as stoptime,
substring_index(group_concat(ipaddr order by (stoptime is null) desc, stoptime desc), ',', 1) as ipaddr
FROM tb
WHERE username LIKE "%OBAM%"
group by username;
However, there are some limitations with this approach -- such as the size of the intermediate string for concatenation. There are other methods, but this works in many cases.
you helped me a lot, i had to make some changes, now i have to concatenate this query with some left joins thank you very much, this is my finnal query: just im afraid for the size of the intermediate string for concatenation, it can be with hundreds, probably with thousands of different results wich problem can i get if its too long? how much is too long?
SELECT username, coalesce(max(stoptime)) as lasstop,
substring_index(group_concat(ipaddr order by starttime desc), ',', 1) as ipaddr,
substring_index(group_concat(stoptime order by starttime desc), ',' ,1) as stopt,
CASE WHEN MAX(CASE WHEN stoptime IS NULL THEN 1 ELSE 0 END) = 0
THEN MAX(stoptime) END as x FROM tb WHERE username LIKE "%%" group by username;
Best regards.

MySQL Select when case

i have those tables and i want to check the same attribute at the same time:
Person
id---name
1----Paul
2----Tom
3----Jim
Age
id---wert------personId
1----28--------1
2----25--------1
3----30--------3
i want to do something like this.
select * from Person p, Age where personId = p.id and CASE WHEN
name = 'Paul' THEN Age > 28 WHEN name = 'Tom' THEN Age <....
How it is possible? With a CASE THEN in the WHERE clause? Please don't think about the structure of the table but only about the principle.
Any Ideas?
Thank
What you're trying to do is possible like so
select
*
from
Person p, Age
where personId = p.id
and CASE
WHEN name = 'Paul' THEN Age > 28
WHEN name = 'Tom' THEN Age <....
WHEN expr then expr that evals to bool
END
CASE WHEN THEN I believe need to be part of an expression, not an expression themselves. It's common use case is in the select, however you can use it in the where.
In a select this would be:
select
case name
when 'paul' then 28
when 'jim' then 30
end
from X
To use it within an where you would do this:
select * from X where age = case name when 'jim' then 28 else 30 end
Depending on what you are attempting to achieve, you may want to consider OR statements instead of case in your where clause.

Need Help With Simple MySQL SELECT

I've got a table of crime data. In a simplified version, it would look like this:
Table Headings:
crime_id, neighborhood, offense
Table Data:
- 1, Old Town, robbery
- 2, Bad Town, theft
- 3, Bad Town, theft
- 4, Uptown, stolen auto
If I SELECT * FROM mytable WHERE offense ='theft', then the results for Bad Town are returned. But, I'm making a ranking, so what I'm really interested in is:
Old Town: 0
Bad Town: theft
Bad Town: theft
Uptown: 0
How do I write a SELECT statement that returns cases where there are thefts, but also returns neighborhoods that don't have an entry for the specified offense?
UPDATE: This my actual SELECT. I'm having problems applying the solution that p.campbell and Gratzy were so kind to post to this SELECT. How do I apply the CASE statement with the COUNT(*)?
SELECT
cbn.neighborhoods AS neighborhoods,
COUNT(*) AS offenses,
TRUNCATE(((na.neighborhood_area_in_sq_meters /1000) * 0.000386102159),2) AS sq_miles,
( COUNT(*) / ((na.neighborhood_area_in_sq_meters /1000) * 0.000386102159) ) AS offenses_per_sq_mile
FROM
wp_crime_by_neighborhood cbn, wp_neighborhood_area na
WHERE
cbn.offense='theft'
AND
cbn.neighborhoods = na.neighborhoods
GROUP BY
cbn.neighborhoods
ORDER BY
offenses_per_sq_mile DESC
If you're looking to make a ranking, wouldn't it be better to get the number of thefts in Bad Town rather than a row for each? Something like this:
select distinct mt.neighborhood, ifnull(total, 0)
from mytable mt
left join (
select neighborhood, count(*) as total
from mytable
where offense = 'theft'
group by neighborhood
) as t on t.neighborhood = mt.neighborhood
Based on the data you gave, this query should return:
Old Town: 0
Bad Town: 2
Uptown: 0
That seems more useful to me for making a ranking. You can easily throw an order by on there.
I would think using a case statement should do it.
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
something like
Select neighborhood,
case offense when 'theft' then offense else '0' end case
from table
Try this:
SELECT cbn.neighborhoods AS neighborhoods,
CASE WHEN IFNULL(COUNT(*),0) > 0 THEN CONCAT(COUNT(*), ' ', offense)
ELSE '0'
END AS offenses
--- ... and the rest of your query
FROM wp_crime_by_neighborhood cbn
INNER JOIN wp_neighborhood_area na
ON cbn.neighborhoods = na.neighborhoods
WHERE cbn.offense='theft'
GROUP BY cbn.neighborhoods
--ORDER BY offenses_per_sq_mile DESC

Mysql: Order by like?

assume that we are performing search using keywords: keyword1, keyword2, keyword3
there are records in database with column "name":
1: John Doe
2: Samuel Doe
3: John Smith
4: Anna Smith
now Query:
SELECT * FROM users WHERE (name LIKE "%John%" OR name LIKE "%Doe%")
it will select records: 1,2,3 (in this order)
but i want to order it by keyword
in example keyword1=John, keyword2=Doe
so it should be listed by keywords: 1,3,2 (because i want to perform search for "Doe" after searching for "John")
I was thinking about SELECT DISTINCT FROM (...... UNION .....)
but it will be much easier to order it somehow in another way (real query is really long)
are there any tricks to create such order?
order by case
when name LIKE "%John%" then 1
when name LIKE "%Doe%" then 2
else 3
end
To build on RedFilter's answer, you could make the rows that have both keywords to be at the top:
order by case
when (name LIKE "%John%" and name LIKE "%Doe%") then 1
when name LIKE "%John%" then 2
when name LIKE "%Doe%" then 3
end
Read up on Boolean Fulltext Searches, with which you can do ordering.
SELECT *
from
(
SELECT u.*, 1 OrderNum
FROM users
WHERE (name LIKE "%John%")
UNION
SELECT u.*, 2 OrderNum
FROM users
WHERE (name LIKE "%Doe%")
)
Order by OrderNum
My example will Order all of the John's Alphabetically followed by the Doe's.
ORDER BY CASE
WHEN name LIKE "John%Doe" THEN CONCAT('a',name)
WHEN name LIKE "John%" THEN CONCAT('b',name)
WHEN name LIKE "%Doe" THEN CONCAT('c',name)
ELSE name
END