mysql query: search in string position - mysql

We have a table which contains card_no information. containing data like:
-----------------------------------------
| id [int(11)] | card_no [varchar(16)] |
-----------------------------------------
| 1 | 0124578965874563 |
| 2 | 1245789658478596 |
| 3 | 8471452369587458 |
-----------------------------------------
Now we need a query to find card number(s) which contains 7 in 6th position. Or which contains 4 in 2nd position.
This is actually needed when we printed card numbers and find some numbers unreadable. so we need to identify the card with rest of the numbers. For example we have data like:
1245_896584_8596
Now we need to identify the card with this data.
Thanks in advance.

You can use function SUBSTRING:
SELECT id, card_no
FROM mytable
WHERE SUBSTRING(card_no, 6, 1) = '7' OR SUBSTRING(card_no, 2, 1) = '4'
Demo here

Use SUBSTR string function
SELECT *
FROM yourtable
WHERE SUBSTR(card_no,2,1) = 4
OR SUBSTR(card_no,6,1) = 7

Use like in where clause and wildcard for exactly one symbol _
Something like
select * from table where card_no like '_____7℅'

Related

mysql query GROUP BY trimed data column

i'm working with MYSQL, and have a problem with group by column that data has to be trimed first.
here is my table:
src
dst
source one
some_character1/dst_one-random_value1
source one
some_character1/dst_one-random_value2
source one
some_character2/dst_two-random_value3
source two
some_character4/dst_two-random_value1
source two
some_character4/dst_three-random_value2
source two
some_character2/dst_three-random_value7
i want to group by this table into like this :
dst_group_by
dst_one
dst_two
dst_three
the dst value has 3 section.
The first section is seperated by '/', and the last section is seperated by '-'.
First section and last section character length is random, and i can determined it.
I only want to group by the middle section.
Is there any effective query to do that ?
Thanks before.
Use SUBSTRING_INDEX to get the between value you want to GROUP BY:
SELECT a.src, a.dst_group_by
FROM (SELECT src, SUBSTRING_INDEX(SUBSTRING_INDEX(dst, '/', -1), '-', 1) AS dst_group_by
FROM sample) a
GROUP BY a.src, a.dst_group_by
Result:
| src | dst_group_by |
|------------|---------------|
| source one | dst_one |
| source one | dst_two |
| source two | dst_two |
| source two | dst_three |
Or if you want to return the DISTINCT values:
SELECT DISTINCT
SUBSTRING_INDEX(SUBSTRING_INDEX(dst, '/', -1), '-', 1) AS dst_group_by
FROM sample
Result:
| dst_group_by |
|---------------|
| dst_one |
| dst_two |
| dst_three |
Fiddle here.
MySQL has substring function, you can define like that
select src,substring(dst,start_position,substring_length)
group by substring(dst,start_position,substring_length)
I don't know if the position is indexed by 0 or by 1 but the idea is like:
select src, substring(dst,16,6)
from table_name
group by substring(dst,16,6)
I hope this can help you

mysql get result from dynamicly formated column name

I have to get result from column which name is generated by the data from another column. I will explain with the following example:
column names in the database:
months | am1 | am2 | am3 | am4 | am5 | am6 | am7 | am8 | am9 | am10 |am11 | am12
I want in my query to get the value from column starting with am + months value
my current query is:
$query = 'select id, iid, contractnumber, concat("am",`months`) as amount from credits where iid > 0';
but this instead of returning the value (71) of the specific am.. column it returns the column name, for example am5
How can I directly access the value of column am5
Thank you for your time !
That is a bad design and you should change it, but if that's what you got, you can use CASE
select id, iid, contractnumber,
case months
when 1 then am1
when 2 then am2
when 3 then am3
when 4 then am4
when 5 then am5
when 6 then am6
when 7 then am7
when 8 then am8
when 9 then am9
when 10 then am10
when 11 then am11
when 12 then am12
end as amount
from credits
where iid > 0

MySQL query - how to look for certain string in the field

I have a table "story" as follows:
+++++++++++++++++++++++++++++++++++++++++++
| id | keywords |
+++++++++++++++++++++++++++++++++++++++++++
| 1 | romance,movie,drama |
| 2 | newmovie,horor,comedy |
| 3 | movie,scifi |
| 4 | newmovie,romance,drama,asia |
| 5 | kids,movie |
+++++++++++++++++++++++++++++++++++++++++++
I try a query to search 'movie' in keywords field as below:
SELECT id FROM story WHERE keywords LIKE '%movie%'
and the result is
1,2,3,4,5
but in this case I wanted the result is 1,3,5 (field value with newmovie not include). Can someone help me how the query to do it?
Thank you for your help..
You want to use find_in_set like this:
SELECT id FROM story WHERE find_in_set('movie', keywords) > 0;
Though you should really consider normalizing your table structure.
In this case, you could've stored one single keyword in one row, then the query would be simply like:
select id from story where keyword = 'movie';
and that would've been the end of it. No heavy string functions needed.
You could have structure like this:
keywords(id, name);
story(story_id,. . ., keyword_id);
then, you could simply join the two like this:
select s.*
from story s
inner join keywords k on s.keyword_id = k.id
where k.name = 'movie';
Your problem is that "newmovie" can be found by "%movie%" you need only search "movie".

merge mysql rows by name when names are slightly different

I'm trying to merge rows in MySQL using the following code:
SELECT
type,
name,
GROUP_CONCAT(code SEPARATOR ',') AS code
FROM
`table1`
WHERE
name = '%name%' AND type = 'type'
GROUP BY
name
However no changes to DB entries occur which is the first problem.
The database looks like this:
type | name | code
-----|-------|-------
A | Milk2 | 143521
-----|-------|-------
A | Milk3 | 987564
-----|-------|-------
B | Oil | 656435
-----|-------|-------
Which I'm trying to make look like:
type | name | code
-----|-------|---------------
A | Milk | 143521, 987564
-----|-------|---------------
B | Oil | 656435
-----|-------|---------------
As you can see, names may be slightly different so this is another problem.
I am wondering whether there is any way to merge rows when, say the first four letters of the name match?
Thanks in advance.
MySQL has several string functions which might help. There's LEFT(name, 4) and you might also want to look at SOUNDEX(name), which implements the Soundex algorithm to hash words alike which sound alike. For example:
select soundex('smith'), soundex('smythe')
+ --------------------- + ---------------------- +
| soundex('smith') | soundex('smythe') |
+ --------------------- + ---------------------- +
| S530 | S530 |
+ --------------------- + ---------------------- +
1 rows
Or, using the example from your question:
select soundex('milk2'), soundex('milk3')
+ --------------------- + --------------------- +
| soundex('milk2') | soundex('milk3') |
+ --------------------- + --------------------- +
| M420 | M420 |
+ --------------------- + --------------------- +
1 rows
Your query would look something like this:
SELECT
type,
GROUP_CONCAT(DISTINCT(name) SEPARATOR ',') AS name, // note that since you've grouped on SOUNDEX(name) you can't just select name (MySQL may let you but will choose the first one
GROUP_CONCAT(code SEPARATOR ',') AS code
FROM
`table1`
WHERE
name LIKE '%name%' AND type = 'type'
GROUP BY
type, SOUNDEX(name)
I hope this is helpful!
You cannot use GROUP BY name here, as the name is always different, and you need to use LIKE instead of = when using wildcards.
The following should give you the result you're looking for
SELECT
type , name, GROUP_CONCAT( code SEPARATOR ',' ) AS all_codes
FROM `table1`
name LIKE '%name%' AND type = 'type'

Reorder rows in a MySQL table

I have a table:
+--------+-------------------+-----------+
| ID | Name | Order |
+--------+-------------------+-----------+
| 1 | John | 1 |
| 2 | Mike | 3 |
| 3 | Daniel | 4 |
| 4 | Lisa | 2 |
| 5 | Joe | 5 |
+--------+-------------------+-----------+
The order can be changed by admin hence the order column. On the admin side I have a form with a select box Insert After: to entries to the database. What query should I use to order+1 after the inserted column.
I want to do this in a such way that keeps server load to a minimum because this table has 1200 rows at present. Is this the correct way to save an order of the table or is there a better way?
Any help appreciated
EDIT:
Here's what I want to do, thanks to itsmatt:
want to reorder row number 1 to be after row 1100, you plan to leave 2-1100 the same and then modify 1 to be 1101 and increment 1101-1200
You need to do this in two steps:
UPDATE MyTable
SET `Order` = `Order` + 1
WHERE `Order` > (SELECT `Order`
FROM MyTable
WHERE ID = <insert-after-id>);
...which will shift the order number of every row further down the list than the person you're inserting after.
Then:
INSERT INTO MyTable (Name, `Order`)
VALUES (Name, (SELECT `Order` + 1 FROM MyTable WHERE ID = <insert-after-id>));
To insert the new row (assuming ID is auto increment), with an order number of one more than the person you're inserting after.
Just add the new row in any normal way and let a later SELECT use ORDER BY to sort. 1200 rows is infinitesimally small by MySQL standards. You really don't have to (and don't want to) keep the physical table sorted. Instead, use keys and indexes to access the table in a way that will give you what you want.
you can
insert into tablename (name, `order`)
values( 'name', select `order`+1 from tablename where name='name')
you can also you id=id_val in your inner select.
Hopefully this is what you're after, the question isn't altogether clear.