2011-05-08 19 views
28

En MySQL, quiero poder buscar '31 - 7', cuando otro valor = '7 - 31'. ¿Cuál es la sintaxis que utilizaría para separar cadenas en MySQL? En PHP, probablemente usaría explode(' - ',$string) y los juntaría. ¿Hay alguna manera de hacer esto en MySQL?Equivalente de explotar() para trabajar con cadenas en MySQL

Antecedentes: Estoy trabajando con puntajes deportivos y quiero probar juegos donde los puntajes son los mismos (y también en la misma fecha): el puntaje listado para cada equipo es retroactivo comparado con el registro de la base de datos de su oponente.

La llamada MySQL ideal sería:

Where opponent1.date = opponent2.date 
    AND opponent1.score = opponent2.score 

(opponent2.score tendría que ser opponent1.score hacia atrás).

+2

Desde el aspecto de la misma, que cree que puede tener algunos defectos fundamentales en el diseño de su base de datos. ¿Puede mostrarnos el esquema de las tablas relevantes, así como los datos de muestra para ellos? –

+1

¿No es el momento de aceptar la respuesta? –

Respuesta

42

MYSQL no tiene explode() como la función incorporada. Pero puede agregar fácilmente una función similar a su DB y luego usarla desde consultas php. Esa función se verá así:

CREATE FUNCTION SPLIT_STRING(str VARCHAR(255), delim VARCHAR(12), pos INT) 
RETURNS VARCHAR(255) 
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, pos), 
     LENGTH(SUBSTRING_INDEX(str, delim, pos-1)) + 1), 
     delim, ''); 

Uso:

SELECT SPLIT_STRING('apple, pear, melon', ',', 1) 

El ejemplo anterior devolverá apple. Creo que será imposible devolver la matriz en MySQL, por lo que debe especificar qué ocurrencia devolver de forma explícita en pos. Avísame si logras usarlo.

+0

Se trabajó como magia :) gracias :) –

+0

El tamaño delimitador de parámetro de tipo de datos VARCHAR (12) debe ser mayor que 12, de modo que no produce resultados imprevisibles con delimitadores grandes. – rahmanisback

+1

Necesito declarar esta función como DETERMINISTIC en uno de mis servidores. Como aquí: RETURNS VARCHAR (255) DETERMINISTIC RETURN – nerkn

15

En primer lugar, debe cambiar la estructura de la base de datos: el puntaje en este caso es algún tipo de valor compuesto y debe almacenarse en dos columnas, por ej. score_host, score_guest.


MySQL no proporciona explode() equivalente sin embargo, en este caso se puede utilizar SUBSTRING() y LOCATE() para cortar la puntuación de un anfitrión y un invitado.

SELECT 
    CONVERT(SUBSTRING(score, 1, LOCATE('-',score) - 2) USING INTEGER) as score_host, 
    CONVERT(SUBSTRING(score, LOCATE('-',score)+2) USING INTEGER) as score_guest 
FROM ...; 

CONVERT() se utiliza para convertir una cadena en serie "23"23.

20

Puede utilizar el procedimiento almacenado de esta manera ..

DELIMITER | 

CREATE PROCEDURE explode(pDelim VARCHAR(32), pStr TEXT)         
BEGIN         
    DROP TABLE IF EXISTS temp_explode;         
    CREATE TEMPORARY TABLE temp_explode (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, word VARCHAR(40));         
    SET @sql := CONCAT('INSERT INTO temp_explode (word) VALUES (', REPLACE(QUOTE(pStr), pDelim, '\'), (\''), ')');         
    PREPARE myStmt FROM @sql;         
    EXECUTE myStmt;         
END | 

DELIMITER ; 
  • ejemplo llamada:

    SET @str = "The quick brown fox jumped over the lazy dog"; 
    SET @delim = " "; 
    
    CALL explode(@delim,@str); 
    SELECT id,word FROM temp_explode; 
    
+11

No estoy seguro de si esto es increíblemente brillante o increíblemente peligroso. – Dexter

+0

increíblemente brillante –

2

As @ arman-p señaló que MYSQL no tiene ninguna explosión(). Sin embargo, creo que la solución presentada en mucho más complicado de lo que necesita ser. Para hacer una comprobación rápida cuando se le da una cadena de lista delimitada por comas (p.g, lista de las claves de tabla para buscar) que hace:

SELECT 
    table_key, field_1, field_2, field_3 
FROM 
    my_table 
WHERE 
    field_3 = 'my_field_3_value' 
    AND (comma_list = table_key 
     OR comma_list LIKE CONCAT(table_key, ',%') 
     OR comma_list LIKE CONCAT('%,', table_key, ',%') 
     OR comma_list LIKE CONCAT('%,', table_key)) 

Esto supone que usted necesita también de comprobar field_3 sobre la mesa también. Si no lo necesita, no agregue esa condición.

3

Utilice esta función. Funciona a las mil maravillas. reemplazar "|" con el char para explotar/dividir y los valores 1,2,3, etc. se basan en el número de entradas en el conjunto de datos: Value_ONE | Value_TWO | Value_THREE.

SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 1), '|', -1) AS PSI, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 2), '|', -1) AS GPM, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 3), '|', -1) AS LIQUID 

Espero que esto ayude.

+0

¿Cómo podría obtener la cantidad de elementos en el conjunto? – Lolums

+0

Desafortunadamente, no necesita saber la cantidad de valores que tiene a mano. En mi caso, sé que necesito tres valores y los cambio de nombre PSI, GPM y LIQUID. si uno de los valores en el conjunto de datos está vacío, SQL devuelve un valor vacío sin dar errores. De esta forma siempre imprimo/echo $ return-> PSI, $ return-> GPM, y $ return-> LIQUID –

+1

@Lolums Puede contar las apariciones del separador: 'ROUND ( (CHAR_LENGTH (' tblNAME''tblFIELD') - CHAR_LENGTH (REPLACE ('tblNAME''tblFIELD'," | "," ")))/CHAR_LENGTH (" | "))' Zero = length es un elemento (sin separador), One = hay dos elementos, etc – FrancescoMM

0

que se enfrentaron mismo problema hoy y resolvieron que, como a continuación, tenga en cuenta que en mi caso, sé el número de elementos de la cadena concatenada, de ahí que pueda recuperarlos de esta manera:

set @var1=0; 
set @var2=0; 
SELECT SUBSTRING_INDEX('value1,value2', ',', 1) into @var1; 
SELECT SUBSTRING_INDEX('value1,value2', ',', -1) into @var2; 

las variables @ var1 y @ var2 tendría los valores similares a explotar().

2

uso SUBSTRING_INDEX, en el siguiente ejemplo he creado una tabla con SCORE1 columna y score2, SCORE1 tiene 3-7, 7-3 score2 etc como se muestra en la imagen. La siguiente consulta es capaz de dividir usando "-" e invertir el orden de score2 y compare con SCORE1

SELECT CONCAT(SUBSTRING_INDEX(score1,'-',1), 
SUBSTRING_INDEX(score1,'-',-1)) as my_score1, 
CONCAT(SUBSTRING_INDEX(score2,'-',-1),SUBSTRING_INDEX(score2,'-',1)) as my_score2 
FROM test HAVING my_score1=my_score2 

scores table

query results

0

si explotará se utiliza junto con foreach para construir una nueva cadena se puede simular explotar mediante el uso de un bucle while así:

CREATE FUNCTION explode_and_loop(sep VARCHAR(),inputstring VARCHAR()) RETURNS VARCHAR() 
BEGIN 
    DECLARE part,returnstring VARCHAR(); 
    DECLARE cnt,partsCnt INT(); 
    SET returnstring = ''; 
    SET partsCnt = ((LENGTH(inputstring) - LENGTH(REPLACE(inputstring,sep,''))) DIV LENGTH(sep); 
    SET cnt = 0; 
    WHILE cnt <= partsCnt DO 
     SET cnt = cnt + 1; 
     SET part = SUBSTRING_INDEX(SUBSTRING_INDEX(inputstring ,sep,cnt),sep,-1); 
     -- DO SOMETHING with the part eg make html: 
     SET returnstring = CONCAT(returnstring,'<li>',part,'</li>') 
    END WHILE; 
    RETURN returnstring; 
END 

este ejemplo devolverá una lista html de las partes. (Legths variables requeridas se tienen que añadir)