alphabet sort in mysql - mysql

I am using the test data "bank" to study mysql on mac. I have a question about the alphabet sort in mysql.
I have a example codeselect cust_id,cust_type_cd,city,state,fed_id from customer order by 2 asc;
The return shows in column 2, "I" is before "B".
Anyone knows what is the reason? Many thanks.

I would guess that cust_type_cd is an ENUM column with "I" ordered before "B" in the enum definition.
Enums sort by the ordinal position of the value in the list defined by the enumeration, not by the alphabetical value.
To sort alphabetically, either define the enum with entries in alphabetical order, or else force the value to be converted to its string value:
... ORDER BY CONCAT(cust_type_cd) ASC
See also http://dev.mysql.com/doc/refman/5.6/en/enum.html#enum-sorting
Note that using a function like that in the ORDER BY clause spoils any chance of using an index for sorting. It will be forced to use a filesort.

Use below Query. It seems there is some space before I character.
select cust_id,trim(cust_type_cd) cust_type_cd,city,state,fed_id from customer order by 2 asc

Using order by column numbers is strictly not recommended. It is especially not used when SELECT * is not used with this. Also it will create problems when somebody alters the table, adds/removes some columns. This link might help you http://blog.sqlauthority.com/2010/12/27/sql-server-order-by-columnname-vs-order-by-columnnumber/

You have to give order by column name in the table
Suppose if you want to sort according to cust_id you have to use
select cust_id,cust_type_cd,city,state,fed_id from customer order by cust_id asc;

Related

How To Order A Hierarchical Table By Two Parameters In MySQL?

I have a table with some hierarchical data in it. I've handled ordering it in a hierarchical way via calculating the path with a trigger but now I wanna sort them with another parameter too.
Take a look at these pictures:
This Is The Table With Hierarchical Data Ordered By Path:
I Expect These Two Rows To Swap Because Row ID = 4 Has A Date Before Row ID = 2:
So How Can I Order Each Level By Date Column?
NOTE:
The ID Is A Random Number Generated By A TRIGGER.
You can use FIND_IN_SET so as to extract the hierarchy level of each row. Then use this in the ORDER BY clause:
SELECT ID, Name, ParentId, Date, Path
FROM mytable
ORDER BY FIND_IN_SET(ID, REPLACE(Path, '.', ',')), Date
Note: We have to use REPLACE function to replace '.' characters with ','
so that FIND_IN_SET works as expected.
Demo here
Alternatively you can modify your trigger so as to generate an additional 'level' field and use this field in the ORDER BY clause of your query.
I think you have to add the date in the path-column on each level, since you cannot simply order by date.
So the path-column should look something like this:
0.date-2015-12-09 22:15:12.parent1.date-2015-12-09 22:15:14.parent4
0.date-2015-12-09 22:15:12.parent1.date-2015-12-09 22:15:17.parent2
In that case, date superceeds the parent-level.
In this situation 1.4 would appear before 1.2, because 1.4 happend before 1.2
The path-column does get a little lengthy, but its the only way you can incorporate your own hierachy, I think
Did I get it this time? :-)
Hope I could help :-)

MySql Sorting complications

I came across a scenario where i have values in a coloumn like
Buno foo
Buno this
Buno that
Buno bar
This is the values of a single coloumn,Now i want to sort this coloumn excluding the
Buno
word,means sorting should be applied on foo,this,that and bar.Is there a way to do this in MySql?
Select * from tableName order by Column_Name
This query can get you the required results, you dont have to worry about the first word.
database query sorts on the first word, if the first word is same, then its sorts according to the second word.
If I am not mistaken, using ORDER BY will sort the entire value in the column, not just the first word, so you should just be able to use ORDER BY to solve your problem...
If you wanted to remove the first section though, you would need to use SUBSTRING in your SELECT and then ORDER BY your substring...
EDIT: Saw your comment above on not knowing how to use SUBSTRING, here is an example using your data:
SELECT SUBSTRING('Buno Foo', 5) AS NOBuno FROM MyTable ORDER BY NOBuno ASC
You can extract the substring of your column from the 6th character onwards (since you always have Buno at the front, which is 5 characters long). To do this use SUBSTRING:
SELECT ...
FROM ...
ORDER BY SUBSTRING(my_column FROM 6)
Note that SELECT SUBSTRING(my_column FROM 6) will return foo,this,that, etc.
If you wanted to be a bit more general and order using the second word, you can try SUBSTRING_INDEX. (read the docs and you'll work it out).

What does SQL clause "GROUP BY 1" mean?

Someone sent me a SQL query where the GROUP BY clause consisted of the statement: GROUP BY 1.
This must be a typo right? No column is given the alias 1. What could this mean? Am I right to assume that this must be a typo?
It means to group by the first column of your result set regardless of what it's called. You can do the same with ORDER BY.
SELECT account_id, open_emp_id
^^^^ ^^^^
1 2
FROM account
GROUP BY 1;
In above query GROUP BY 1 refers to the first column in select statement which is
account_id.
You also can specify in ORDER BY.
Note : The number in ORDER BY and GROUP BY always start with 1 not with 0.
In addition to grouping by the field name, you may also group by ordinal, or position of the field within the table. 1 corresponds to the first field (regardless of name), 2 is the second, and so on.
This is generally ill-advised if you're grouping on something specific, since the table/view structure may change. Additionally, it may be difficult to quickly comprehend what your SQL query is doing if you haven’t memorized the table fields.
If you are returning a unique set, or quickly performing a temporary lookup, this is nice shorthand syntax to reduce typing. If you plan to run the query again at some point, I’d recommend replacing those to avoid future confusion and unexpected complications (due to scheme changes).
It will group by first field in the select clause
That means *"group by the 1st column in your select clause". Always use GROUP BY 1 together with ORDER BY 1.
You can also use GROUP BY 1,2,3... It is convenient, but you need to pay attention to that condition; the result may not be what you want if someone has modified your select columns and it's not visualized.
It will group by the column position you put after the group by clause.
for example if you run 'SELECT SALESMAN_NAME, SUM(SALES) FROM SALES GROUP BY 1'
it will group by SALESMAN_NAME.
One risk on doing that is if you run 'Select *' and for some reason you recreate the table with columns on a different order, it will give you a different result than you would expect.

avoid Sorting by the MYSQL IN Keyword

When querying the db for a set of ids, mysql doesnot provide the results in the order by which the ids were specified. The query i am using is the following:
SELECT id ,title, date FROM Table WHERE id in (7,1,5,9,3)
in return the result provided is in the order 1,3,5,7,9.
How can i avoid this auto sorting
If you want to order your result by id in the order specified in the in clause you can make use of FIND_IN_SET as:
SELECT id ,title, date
FROM Table
WHERE id in (7,1,5,9,3)
ORDER BY FIND_IN_SET(id,'7,1,5,9,3')
There is no auto-sorting or default sorting going on. The sorting you're seeing is most likely the natural sorting of rows within the table, ie. the order they were inserted. If you want the results sorted in some other way, specify it using an ORDER BY clause. There is no way in SQL to specify that a sort order should follow the ordering of items in an IN clause.
The WHERE clause in SQL does not affect the sort order; the ORDER BY clause does that.
If you don't specify a sort order using ORDER BY, SQL will pick its own order, which will typically be the order of the primary key, but could be anything.
If you want the records in a particular order, you need to specify an ORDER BY clause that tells SQL the order you want.
If the order you want is based solely on that odd sequence of IDs, then you'd need to specify that in the ORDER BY clause. It will be tricky to specify exactly that. It is possible, but will need some awkward SQL code, and will slow down the query significantly (due to it no longer using a key to find the records).
If your desired ID sequence is because of some other factor that is more predictable (say for example, you actually want the records in alphabetical name order), you can just do ORDER BY name (or whatever the field is).
If you really want to sort by the ID in an arbitrary sequence, you may need to generate a temporary field which you can use to sort by:
SELECT *,
CASE id
WHEN 7 THEN 1
WHEN 1 THEN 2
WHEN 5 THEN 3
WHEN 3 THEN 4
WHEN 9 THEN 5
END AS mysortorder
FROM mytable
WHERE id in (7,1,5,9,3)
ORDER BY mysortorder;
The behaviour you are seeing is a result of query optimisation, I expect that you have an index on id so that the IN statement will use the index to return records in the most efficient way. As an ORDER BY statement has not been specified the database will assume that the order of the return records is not important and will optimise for speed. (Checkout "EXPLAIN SELECT")
CodeAddicts or Spudley's answer will give the result you want. An alternative is assigning a priority to the id's in "mytable" (or another table) and using this to order the records as desired.

Creating a linked list or similar queue in MySQL?

I have a table of items that need to be displayed in a certain order, but that order can be changed. Items can be added at the beginning, end, or in the middle, and items can be rearranged. How can I set up the table to keep track of that order in such a way that it's easy to modify but the list can also be fetched in order with a single query?
For example, I could have a "NEXT_ID" column to do it linked list-style, but then how would I run a SELECT query to get the rows in order of the NEXT_ID chain?
Apologies in advance for the super-obvious solution I'm probably missing.
I have this problem often, and I solved it with a simple solution : an extra column called Sort Order (or DisplayOrder, whatever floats your boat really) . This allows me the flexibility to use auto-generated, auto-incremented ID column and have a special pre-defined sort.
In my case, I need them to come out of the database with an alphabetical order except that some items like "Other" and "N/A" are always last.
ProdID ProdText SortOrder
2 "Anchovies" 1
3 "Rivet" 2
4 "N/A" 4
5 "Other" 3
SELECT ProdID, ProdText ORDER BY Sort Order
Create a column in the table that represents the sort order. Put an index on this column so that the MySQL engine can retrieve based on this column quickly. When you change the order, update the values in this field for all records to keep it consistent.
For example, when you insert a new record in the middle:
UPDATE table SET sort_order = sort_order + 1 WHERE sort_order >= 5;
INSERT INTO table (sort_order, column1, column2) VALUES (5, 'value1', 'value2');
Something more complicated, like moving #3 down to #6 and sliding all others up:
UPDATE table
SET sort_order = Case sort_order When 3 Then 6 Else sort_order - 1 End
WHERE sort_order BETWEEN 3 AND 6;
If you want to avoid the sort order, you can try a "parent" column and consider the linked list to be a special case of a tree like structure. This article may help.
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
There are other articles out there:
http://ferdychristant.com/blog//archive/DOMM-7QJPM7
Keep in mind that selecting a long linked list may degrade performance though.
Unless I am misunderstanding what you are looking for it would seem you could just add a DISPLAY_ORDER column that is a numeric index of how things should be returned. This can easily be changed and rearranged. Plus value can be used in order by.
easiest solution: use a column named "display_order" in which you set 1,2,3 and so on. The query would be sorted with "ORDER BY display_order".
To edit this (if youre in a website related environment) use javascript with + and - buttons for example. everytime you do + the number increments and if something with the number exists itll get decreased so they switch positions.