0

以下のクエリを使用してデータをフェッチするために使用find_in_setしていますが、正しく動作します。

SELECT * 
FROM A 
WHERE FIND_IN_SET(
column1,
(
 SELECT column1 
 FROM B 
 WHERE  id = 21)
);

ここで、このクエリSELECT column1 FROM B WHERE id = 21は次のような結果を返しますが、使用する必要が'175587,282329' ある'175587,282329'最も高い値がここに来ることを望み282329ます。ありがとう

4

2 に答える 2

1

私はこれを解決策として真剣に提唱しているわけではありませんが、次のハックを検討してください...

 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 |
 +----+--------+-------+
于 2014-08-09T11:03:13.600 に答える
1

TableAがそのように見えると仮定します

CREATE TABLE A (
    id INT,
    columnA INT
);

次のアプローチでは、最大 100 個の分離された値に対して (私が理解しているように) 望ましい結果が得られます。

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
;

デモ

説明

最も内側の SELECT は、1 から 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

この方法は、そのようなリストを生成するための通常の方法であり、高速です。

ネストされた SUBSTRING 呼び出しは、値を取得する責任があり、次のようにテストします

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', 1), ',', -1) FROM B
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column1, ',', 2), ',', -1) FROM B

それが何をするかについての感覚を得るために。検索を制限します

1 + LENGTH(column1) - LENGTH(REPLACE(column1, ',', ''))

値よりカンマが 1 つ少なく、最後の値も必要だからです。だから声明は

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

id = 21 に対応する column1 の値のリストを返します。

残りは、このリストの最大値を TableA の対応する列に単純に結合することです。

于 2014-08-09T11:41:58.863 に答える