mysql query GROUP BY trimed data column - mysql

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

Related

Remove All Backslash into string in MySQL query

I have this type of string
'160f7a4a-766a-4c23-a155-8bd3f7389f77\', \'63233bfc-b663-4c73-890b-00a48d79c4dc'
In one column and I want like
'160f7a4a-766a-4c23-a155-8bd3f7389f77','63233bfc-b663-4c73-890b-00a48d79c4dc'
This type of result in MySQL
i have to perform query like
SELECT * FROM kapp_staging.kols where `kol_id` in (select REPLACE(json_id,'\'',"'") FROM kapp_staging.news_items
where `id` = '991'))
in where in clause i have subquery and in subquery
i geting
'160f7a4a-766a-4c23-a155-8bd3f7389f77\', \'63233bfc-b663-4c73-890b-00a48d79c4dc'
this type of value
so i need to remove \ from value so my where in query work fine.
i have data like:
Kols table
| id | kol_id | name | data |
|----|---------------------------------------- |---------| ------|
| 1 |160f7a4a-766a-4c23-a155-8bd3f7389f77 | balwant | data |
| 2 |63233bfc-b663-4c73-890b-00a48d79c4dc | vikram | data |
news items
| id | json_id | data |
|----|-----------------------------------------------------------------------------------------|---------|
| 991 | {'\160f7a4a-766a-4c23-a155-8bd3f7389f77\','\160f7a4a-766a-4c23-a155-8bd3f7389f77\'} | data |
I tried many ways but didn't get this response.
Thanks in Advance : )
The backslashes aren't in the data, they're just used to escape the quotes when inserting into the table. So you don't need to remove them.
However, you can't use IN to match values in a comma-delimited list, you need to use FIND_IN_SET(); see Search with comma-separated value mysql
You also need to remove the quotes and curly braces before you can use FIND_IN_SET().
SELECT DISTINCT k.*
FROM kols AS k
JOIN news_items AS n
ON FIND_IN_SET(k.kol_id,
REPLACE(REPLACE(REPLACE(json_id, '{', ''), '}', ''), "'", ''))
DEMO
Things would be much easier if you normalized your data and put the list of IDs into a separate table with one row per ID.

Displaying date between two dates without ( IIf and Citeria)

I'm new to access and coding so please bear with me.
I want my [Exp] dates that fall between 1/12/2020 and 1/7/2021 to be shown/displayed in [Exp2] record and if it doesn't fall between the two mentioned dates then show/display nothing in Exp2 record.
Example: |
| Exp | Exp2 |
| 1/5/2020 | |
| 3/8/2020 | |
| 12/13/2020| 12.13.2020 |
see in Exp2 only 3rd record is shown/displayed while the first and second are empty.
enter image description here
enter image description here
Use a query like this:
Select
[Exp],
IIf([Exp] Between #2020-12-01# And #2021-07-01#, [Exp], Null) As Exp2
From
YourTable
or use a subquery (slower):
Select
[Exp],
(Select
First(T.Exp)
From
YourTable As T
Where
T.Exp = YourTable.Exp
And
T.Exp Between #2020-12-01# And #2021-07-01#) As Exp2
From
YourTable

MySQL pattern matching - finding the match

I'm working with a MySQL database that contains a substantial amount of data (about 10.000 records). The data in the database is logging of a machine maintenance, one of the fields contains a basic timeline (just steps that are timestamped) explaining all the work done. In this field I'm looking for certain strings that can indicate certain procedures (i.e. ABC123.ABC, abc111.abc, abc001.abc).
I'm looking for matches in this field with pattern matching like such
SELECT * FROM [tablename]
WHERE `work_performed` LIKE '% ______.___ %'
ORDER BY id DESC;`
The regex is very general but I can specify that further myself.
However, since the field which contains the string I'm looking for can be very large (up to 2364763 characters) i want to return the records matching the pattern specified but I also want to return a field that contains just the matched expression so I can confirm it is actually what I'm looking for and can use that string further.
I have found people with the same issue but I cannot reproduce their results.
Something like this might work?:
SELECT *, SUBSTRING(`work_performed`,
patindex('%[0-9][0-9][0-9]%', `work_performed`)-1, 5) as match
FROM [tablename]
WHERE `work_performed`LIKE '% ______.___ %'
I would like to get output that looks somewhat like this:
+----+-------------------------------------------+------------+
| id | work_performed | match |
+----+-------------------------------------------+------------+
| 1 | 2017-02-26|10:59| Arrival: admin1 | ABCD12.adb |
| | 2017-02-26|10:59| diagnosed error ab-0001 | |
| | 2017-02-26|11:02| ran ABCD12.adb | |
| | 2017-02-26|11:03| system back online | |
+----+-------------------------------------------+------------+
| 2 | 2017-02-26|10:59| Arrival: admin34 | abc123.ags |
| | 2017-02-26|10:59| diagnosed error WP1234 | |
| | 2017-02-26|11:02| ran abc123.ags | |
| | 2017-02-26|11:03| system back online | |
+----+-------------------------------------------+------------+
I apologise if I didn't give enough details but I'm an intern at a major company and we have very strict rules about confidentiality.
If there is a need for any additional information I will try to.
EDIT
I have been trying to search for the string I'm looking for with regexp, but I cant get it to work as I want to, here is what I tried:
SELECT * FROM tablename
WHERE `work_performed` regexp '% ([a-z]^3)([0-9]^3).([a-z]^3) %'
ORDER BY id DESC;
The solution using CONCAT, SUBSTR, SUBSTRING_INDEX and LOCATE functions:
SELECT
CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(work_performed, '.', 1), ' ', - 1),
'.',
SUBSTR(SUBSTRING_INDEX(work_performed, '.', - 1), 1,
LOCATE(' ', SUBSTRING_INDEX(work_performed, '.', - 1))
)
) m
FROM
tablename
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html
DEMO link

mysql query: search in string position

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℅'

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'