How to order mysql rows in custom order? - mysql

I want to order mysql records by one column whose values start with N,Y,F,P,U. Type of column is VARCHAR. I want to order by column according to first letter of this column's values.
Specific order is N - Y - F - P - U.
So first record must be that one with some column's value N, the second record has that column's value starting with Y and so on.
How to order by first letter of column's value?

SELECT
...
ORDER BY
CASE SUBSTR(one_column,1,1)
WHEN 'N' THEN 0
WHEN 'Y' THEN 1
WHEN 'F' THEN 2
WHEN 'P' THEN 3
WHEN 'U' THEN 4
ELSE 5
END
...or join to lookup table of values, or use IF functions to map the char to a number.

Related

MySQL comparing a substring with another String and if it matches get me the match percentage

If I have a column `Full_Names' in table cust and another Column as 'Models' in same table cust. The Full_name column contains ABCD and Models column contain AB then how can I write a query to get Models matches Full_Names 50% since only first two letters matched the whole string.
Thanks in Advance.
You can do:
case when locate(models, full_names)
then char_length(models) / char_length(full_name)
else 0
end match_ratio
This can be shorten as:
(locate(models, full_names) > 0) * char_length(models) / char_length(full_name)
This gives you a numeric value between 0 and 1 that represents the match ratio. If you want a percentage, you can multiply that by 100/

Identifying one field from three fields where the value of field is equal to specific number in `MySQL`

I have three fields (a,b,c) in one table: sample_table.
One of the value in these three fields is 999.
I want to select only that column whose value is 999.
Let's assume b = 999.
I want to select these three with b value as 1 and other two values as 0.
Note that there are many rows with one of the values as 999.
If I understand your question, a simple case when will work:
select
case when b = 999 then 1
when a = 999 then 0
when c = 999 then 0
end
from sample_table

Find greatest value of defined string in MySQL from a particular field (separated by comma)

We need to get the row, which has value in cmts greater than given value(4000), below is our example table structure
id cmts
1 1000,2000,3000,4000
2 1100,2200,3300,4400
Output should be the 2nd row(ID 2).
SELECT *
FROM cmts
WHERE CONVERT(SUBSTR(cmts, SUBSTRING_INDEX(cmts,',',-1), LEN(cmts)), ,UNSIGNED INTEGER)>4000

MySQL - return records for clients unless they have a specific value and only that value

Trying to wrap my head around how to do this query - I want to return a list of client records and need to exclude clients if they had only a specific value and no other values.
For example
c# value
1 X
1 Y
2 X
3 Y
I want all the records for clients 1 and 3, since they had a value other than X. I do not want client 2, because that client had ONLY X.
I for example want returned in this case:
1 X
1 Y
3 Y
Of course, I could have lots of other records with other client id's and values, but I want to eliminate only the ones that have a single "X" value and no other values.
Maybe using a sub-query?
Try this:
SELECT client, value FROM myTable where `client` in
(select distinct(client) from myTable where value !='X');
Returns:
Client Value
1 X
1 Y
3 Y
Something like this
SELECT ABB2.*
FROM
mytable AS ABB2
JOIN
(SELECT c
FROM mytable
WHERE value <> "X"
GROUP BY c) AS ABB1 ON ABB1.c = ABB2.c
GROUP BY ABB2.c, ABB2.value
It's faster than using a WHERE clause to identify the sub query results (as in Mike's answer)

Populate column with number of substrings in another column

I have two tables "A" and "B". Table "A" has two columns "Body" and "Number." The column "Number" is empty, the purpose is to populate it.
Table A: Body / Number
ABABCDEF /
IJKLMNOP /
QRSTUVWKYZ /
Table "B" only has one column:
Table B: Values
AB
CD
QR
Here is what I am looking for as a result:
ABABCDEF / 3
IJKLMNOP / 0
QRSTUVWKYZ / 1
In other words, I want to create a query that looks up, for each string in the "Body" column, how many times the substrings in the "Values" column appear.
How would you advise me to do that?
Here's the finished query; explanation will follow:
SELECT
Body,
SUM(
CASE WHEN Value IS NULL THEN 0
ELSE (LENGTH(Body) - LENGTH(REPLACE(Body, Value, ''))) / LENGTH(Value)
END
) AS Val
FROM (
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
) CharMatch
GROUP BY Body
There's a SQL Fiddle here.
Now for the explanation...
The inner query matches TableA strings with TableB substrings:
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
Its results are:
BODY VALUE
-------------------- -----
ABABCDEF AB
ABABCDEF CD
IJKLMNOP
QRSTUVWKYZ QR
If you just count these you'll only get a value of 2 for the ABABCDEF string because it just looks for the existence of the substrings and doesn't take into consideration that AB occurs twice.
MySQL doesn't appear to have an OCCURS type function, so to count the occurrences I used the workaround of comparing the length of the string to its length with the target string removed, divided by the length of the target string. Here's an explanation:
REPLACE('ABABCDEF', 'AB', '') ==> 'CDEF'
LENGTH('ABABCDEF') ==> 8
LENGTH('CDEF') ==> 4
So the length of the string with all AB occurrences removed is 8 - 4, or 4. Divide the 4 by 2 (LENGTH('AB')) to get the number of AB occurrences: 2
String IJKLMNOP will mess this up. It doesn't have any of the target values so there's a divide by zero risk. The CASE inside the SUM protects against this.
You want an update query:
update A
set cnt = (select sum((length(a.body) - length(replace(a.body, b.value, '')) / length(b.value))
from b
)
This uses a little trick for counting the number of occurrence of b.value in a given string. It replaces each occurrence with an empty string and counts the difference in length of the strings. This is divided by the length of the string being replaced.
If you just wanted the number of matches (so the first value would be "2" instead of "3"):
update A
set cnt = (select count(*)
from b
where a.body like concat('%', b.value, '%')
)