Pregunta

Todo lo que he visto hasta el momento se trata de la eliminación de entradas duplicadas en una base de datos de forma automática. Quiero hacer hincapié en el principio de este que no hay datos duplicados en la base de datos. También voy a empezar con el hecho de que mucho todavía estoy aprendiendo sobre el diseño de RDBMS, la normalización, las relaciones y, sobre todo, SQL!

Tengo una tabla de clientes, con un ClientID (PK) y un client_name. Tengo una tabla de funciones, con un roleid (PK) y un ROLE_NAME. Cualquier cliente puede tener varios roles asociados con ella. Así que creé una mesa client_role_link, con ClientID y roleid como los dos campos. Luego ejecutar esto:

SELECT client.client_name, role.role_name FROM client 
  LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid 
  LEFT JOIN role ON client_role_link.roleid=role.roleid 
  WHERE (role.roleid='1' OR role.roleid='2')

Así que vamos a decir que tengo un cliente que tiene dos roles asociados a ella (papeles '1' y '2'). Esta consulta devuelve dos filas, una para cada función. Cuando llego a estos resultados respaldan que estoy usando un bucle while para pasar por los resultados y salida de ellos, en una lista <select>. A continuación, está causando dos de <option> con el mismo cliente que se indican.

entiendo por qué mi consulta devuelve dos filas, tiene sentido. Así que aquí viene la pregunta dos veces:

  1. ¿Hay un mejor diseño de base de datos / tabla que debo utilizar, o una consulta más optimizado?
  2. O es esto algo que debe manejar en el PHP? Si es así, ¿hay una solución más elegante que la adición de todos los resultados en una matriz, a continuación, un bucle de vuelta a través de la matriz y la eliminación de duplicados?

Los pensamientos?

¿Fue útil?

Solución

Si desea mostrar los dos papeles, a continuación, su consulta es OK.

MySQL no soporta tipos de datos de la matriz, por lo que debe llenar una matriz asociativa en el lado PHP usando el conjunto de resultados con los nombres de clientes duplicados.

Si sólo tiene que mostrar a los clientes que tengan una de las funciones, utilice esta consulta:

SELECT  c.*
FROM    client c
WHERE   c.clientid IN
        (
        SELECT  roleid
        FROM    client_role_link crl
        WHERE   crl.roleid IN (1, 2)
        )

Esto devolverá un registro por cliente, pero no mostrará ninguna función.

La tercera forma implosionaría los nombres de rol en el lado del servidor:

SELECT  c.*, GROUP_CONCAT(role_name SEPARATOR ';') AS roles
FROM    client c
LEFT JOIN
        client_role_link crl
ON      crl.clientid = c.clientid
        AND crl.roleid IN (1, 2)
LEFT JOIN
        role r
ON      r.roleid = crl.roleid
GROUP BY
        c.id

y explotar ellos al otro lado PHP, pero que seguro que los nombres de función no se mezclará con el separador.

Otros consejos

Se puede usar mysql_fetch_assoc () para conseguirlos de nuevo en forma de matriz. Posteriormente, se podría tener algo como código no probado, pero puede funcionar

$sql = "SELECT client.id, client.client_name, role.role_name FROM client LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid LEFT JOIN role ON client_role_link.roleid=role.roleid WHERE (role.roleid='1' OR role.roleid='2')";
$result = mysql_query($sql);
$res = array();
while ($row = mysql_fetch_assoc($result)) {
    $res[$row['id']]['roles'][] = $row['role_name'];
    $res[$row['id']]['client_name'] = $row['client_name']; //you'll be overwriting each iteration probably a better way
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top