Reputation: 1094
I am using find_in_set
for fetching data using below query and it works correctly.
SELECT *
FROM A
WHERE FIND_IN_SET(
column1,
(
SELECT column1
FROM B
WHERE id = 21)
);
Here this query SELECT column1 FROM B WHERE id = 21
gives result like '175587,282329'
but I want that '175587,282329'
whichever highest value will come here that I should use.In this case,It would be 282329
.but Is will any number of comma seperated values.
Thanks
Upvotes: 0
Views: 633
Reputation: 10336
Assuming TableA looks as that
CREATE TABLE A (
id INT,
columnA INT
);
following approach would give you the desired result (as I understand it) for up to 100 separated values:
SELECT * FROM A
INNER JOIN (
SELECT MAX(t.value) as max_value
FROM (
SELECT
id,
SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', n.n), ',', -1) value
FROM B CROSS JOIN (
-- build for up to 100 separated values
SELECT
a.N + b.N * 10 + 1 AS 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 <= (1 + LENGTH(column1) - LENGTH(REPLACE(column1, ',', '')))
AND B.id = 21
) t
) t1
ON A.columnA = t1.max_value
;
The most inner SELECT creates a temporary table with the values of 1 to 100:
SELECT
a.N + b.N * 10 + 1 AS 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
This method is a usual approach to generate such lists and is fast.
The nested SUBSTRING call is responsible to get our values, test it with
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', 1), ',', -1) FROM B
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', 2), ',', -1) FROM B
to get a feeling for what it does. We limit our search with
1 + LENGTH(column1) - LENGTH(REPLACE(column1, ',', ''))
because we have one comma less than values and we need the last value too. So the statement
SELECT
id,
SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', n.n), ',', -1) value
FROM B CROSS JOIN (
SELECT
a.N + b.N * 10 + 1 AS 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 <= (1 + LENGTH(column1) - LENGTH(REPLACE(column1, ',', '')))
AND B.id = 21
will return the list of the values from the column1 corresponding to id = 21.
The rest is a simple join on the maximum value of this list to the corresponding column of TableA.
Upvotes: 1
Reputation: 33945
While I don't seriously advocate this as a solution, consider the following hack...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,string VARCHAR(20) NOT NULL UNIQUE
);
INSERT INTO my_table(string) VALUES
('1,2,3'),
('2,3,4'),
('3,4,5'),
('1,3,5'),
('2,4,6');
SELECT * FROM my_table;
+----+--------+
| id | string |
+----+--------+
| 1 | 1,2,3 |
| 4 | 1,3,5 |
| 2 | 2,3,4 |
| 5 | 2,4,6 |
| 3 | 3,4,5 |
+----+--------+
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT x.*
, GROUP_CONCAT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(string,',',i+1),',',-1) ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(string,',',i),',',-1) DESC) n
FROM my_table x
, ints
GROUP
BY id;
+----+--------+-------+
| id | string | n |
+----+--------+-------+
| 1 | 1,2,3 | 3,2,1 |
| 2 | 2,3,4 | 4,3,2 |
| 3 | 3,4,5 | 5,4,3 |
| 4 | 1,3,5 | 5,3,1 |
| 5 | 2,4,6 | 6,4,2 |
+----+--------+-------+
Upvotes: 1