Efficiently match highest category - mysql

I have a table with 6 digit numbers that can range from 0-9 and I would match that against a number in 6 categories
first number match
first two number match
first three number match
first four number match
first five number match
all numbers match
But only the highest category per matching number should be selected. An example
Number: 123456
If one has the number [123]756 then this would fall into category first three number match
On number 023456 then this would be no match
I created a fiddle for it https://www.db-fiddle.com/f/TZCrFPnJpkw4fyxA5Q6mR/1
Here an example:
Numbers:
number
123456
123000
023456
123477
133456
Number to match against: 123456 should return
common_digits
number
6
123456
3
123000
0
023456
4
123477
1
133456
What would be an efficient method? The brute force solution would be a double loop I suppose starting with 6 matches, 5 matches, ...

SELECT #number tested_number, 7 - LENGTH(nums.num) common_digits, bids.*
FROM bids
JOIN (SELECT 1 num UNION
SELECT 10 UNION
SELECT 100 UNION
SELECT 1000 UNION
SELECT 10000 UNION
SELECT 100000) nums
WHERE #number DIV nums.num = bids.ticketNumber DIV nums.num
ORDER BY nums.num LIMIT 1;
https://www.db-fiddle.com/f/TZCrFPnJpkw4fyxA5Q6mR/4

You can do:
select *
from (
select 6 as score, b.* from bids b where ticketNumber like '123456%'
union all select 5, b.* from bids b where ticketNumber like '12345%'
union all select 4, b.* from bids b where ticketNumber like '1234%'
union all select 3, b.* from bids b where ticketNumber like '123%'
union all select 2, b.* from bids b where ticketNumber like '12%'
union all select 1, b.* from bids b where ticketNumber like '1%'
) x
order by score desc
limit 1
Result:
score id roundId address ticketNumber
------ --- -------- -------- ------------
6 1 1 12345 123456
See example at DB Fiddle.
Alternatively you can use a recursive CTE, but that's not available in MySQL 5.7 (as your fiddle implies).

Related

MySQL query for selecting multiple rows as arrays of those rows data

Is there a way to select frist 3 rows and after that next 3 ( offset 3 ) and get the result as two arrays in a single query ? Something like:
(SELECT * FROM product WHERE 1 LIMIT 3) as first_array
(SELECT * FROM product WHERE 1 OFFSET 3 LIMIT 3) as second_array
Hope you understand me. Sorry about the explanation just dont't know how to explain in other way.
Lets say I only want the ids - output example:
id_1 id_2
1 4
2 5
3 6
What I have tried from the answers below the post is :
SELECT id as id_1 FROM `ct_product` WHERE 1 LIMIT 3
UNION ALL
SELECT id as id_2 FROM `ct_product` WHERE 1 LIMIT 3 OFFSET 3
The result is strange for me. It seems it returns only the second query results and they are not the 4th 5th and 6th row but the 5th 6th and 3th (in this order).
My table rows are:
id
1
2
3
4
5
6
7
You could do it with this query:
SELECT a1.id, a2.id
FROM (SELECT *, #rownum1:=#rownum1+1 AS rownum
FROM (SELECT id
FROM `ct_product`
LIMIT 3
) art
JOIN (SELECT #rownum1 := 0) r
) a1
JOIN (SELECT *, #rownum2:=#rownum2+1 AS rownum
FROM (SELECT id
FROM `ct_product`
LIMIT 3, 3
) art
JOIN (SELECT #rownum2 := 0) r
) a2
ON a1.rownum = a2.rownum
Output:
id id
1 4
2 5
3 6
This query works by creating two new tables with artificially generated row numbers (#rownum1 and #rownum2) from the first 3 and the second 3 rows in the original table. They are then JOINed on matching row numbers to get the desired result.

MySQL Count distinct values from one column

I have a table having three columns:
A B C
1 2 2
2 2 2
3 1 1
4 1 2
I want the count of those values which have C equal to 2 but with distinct values of B
So in this case for C = 2, count = 2 (B=2 and B=1)
I used the following command:
Select count(*) from mytable where C=2 group by (B)
but it yields:
count(*)
3
I have tried using "distinct" but it can't be use to select from one column
Have you tried
SELECT COUNT(DISTINCT B) FROM mytable WHERE C = 2;
Use sub query like this:
Select count(*) from (
select distinct B where c=2
)

Mysql Query to Merge 3 tables into 1 Table

TO Plot Each Input table I have Separate query, need to apply functionality on that queries and want to create Single query for Output Table
Select Distinct Names, SUM(count) from
(Select Query table 1
union
Select Query table 2
union
Select Query table 3) table group by Names;
this query Not adding count properly Niether Sorting Names properly Whats wrong with this ?
Input Table 1 :-
Names count
bob 3
pol 4
Input Table 2 :-
Names count
bob 5
0 - name may be missing here neglect this entry
Input Table 3 :-
Names count
james 4
pol 7
bob 1
Expected output table :-
Names count
bob 9
pol 11
james 4
You can use UNION and them sum of those.
select sum(a), sum(b) from
(select 2 as a, 1 as b
union select 3 as a, 6 as b
union select 4 as a, 1 as b) as b
Try this query
select `Name`,sum(`Count`) total from ( select `Name`,`Count` from `table1` union all select `Name`,`Count` from `table2` union all select `Name`,`Count` from `table3` ) tot group by `Name`
May this help you.

Explode prevsiouly rolled up data in SQL

I have data as follows:
Product Quantity
A 3
B 2
This is data that as been previously rolled up at the product level. Assume there are only two columns as of now.
I want an output as follows:
Product Quantity
A 1
A 1
A 1
B 1
B 1
You could use a trick like this:
SELECT Product, 1 AS Quantity
FROM
Products INNER JOIN (
SELECT 1 AS q UNION ALL
SELECT 2 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 3 UNION ALL SELECT 3
) quantities
ON Products.Quantity = quantities.q
of course, this query is limited to a quantity of 3, but you can add more quantities to your subquery if they are of a limited amount.

SQL query of multiple values in one cell

There is a table(Course Interests) which has all the values in one cell. But those values are just ids and I want to join them with another table(Course) so I can know their names.
Course Interests:
MemberID MemberName CoursesInterested
-------------- --------------------- --------------
1 Al 1,4,5,6
2 A2 3,5,6
Course Table:
CourseId Course
-------------- ---------------------
1 MBA
2 Languages
3 English
4 French
5 Fashion
6 IT
Desired Output:
MemberID MemberName CoursesInterested
-------------- --------------------- --------------
1 Al MBA,French,Fashion,IT
2 A2 English,Fashion,IT
I would like to do a SQL query in MySql that can help me to extract the desired output. I know how to do it in the opposite way(join values to one cell), but I've struggling on seek a way to separate the ids and do a cross-join into another table.
I'll appreciate any help from the community. Thanks
Use FIND_IN_SET to search for something in a comma-delimited list.
SELECT i.MemberID, i.MemberName, GROUP_CONCAT(c.Course) AS CoursesInterested
FROM CourseInterests AS i
JOIN Course AS c ON FIND_IN_SET(c.CourseId, i.CoursesInterested)
However, it would be better to create a relation table instead of storing the courses in a single column. This type of join cannot be optimized using an index, so it will be expensive for a large table.
Try this Out:
SELECT MemberID,MemberName,Group_Concat(C.Course) from
(
SELECT MemberID,MemberName,SUBSTRING_INDEX(SUBSTRING_INDEX(t.CoursesInterested, ',', n.n), ',', -1) value
FROM Table1 t CROSS JOIN
(
SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) n
WHERE n.n <= 1 + (LENGTH(t.CoursesInterested) - LENGTH(REPLACE(t.CoursesInterested, ',', '')))
ORDER BY MemberID,value
) T JOIN course C ON T.value = C.CourseId
Group By MemberID,MemberName
Fiddle Demo
Output:
MemberID MemberName CoursesInterested
-------------- --------------------- --------------
1 Al MBA,French,Fashion,IT
2 A2 English,Fashion,IT