SQL - Distinct para tres campos mysql

   
Vista:

Distinct para tres campos mysql

Publicado por vanessa (4 intervenciones) el 07/06/2017 00:38:15
Hola buenas tardes esta ves me encuentro con un problema en el cual lleno un combobox con una base de datos de 3 columnas diferentes ( esp1, esp2 esp3) pero no he podido hacer que nada mas me muestre los que no están repetidos .. espero y pudieran ayudarme

de antemano muchas gracias

mi combobox aparece asi
y no deverian aparecer los datos repetidos

se los agradecere mucho


1

le eh intentado de varias maneras no he podido
mi codigo
1
$clavebuscadah=mysql_query("SELECT distinct w1.esp1, w1.esp2, w1.esp3 FROM (select esp1, esp2, esp3 from especialidad) group by w1.esp1, w1.esp2, w1.esp3",$conexion) )
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Distinct para tres campos mysql

Publicado por leonardo_josue (1079 intervenciones) el 07/06/2017 15:59:14
Hola vanessa:

De entrada te comento que tal como tienes tu tabla, tienes un terrible error de diseño, una tabla no debe tener más de una columna que almacene la misma información, ya que esto es lo mismo que tener campos multivaluados, es más, me atrevería a decir que para algunos casos estás dejando una o más columnas vacías con valores nulos, lo cual también es un terrible horror... Si estoy en lo correcto lo que tratas de almacenar serían las especialidades que puede tener un doctor... ¿cuántas especialidades puede tener? según tu modelo de 1 a 3, pero ¿qué pasa si tiene más de tres especialidades? pasa que por tu modelo no podrías guardar la información.

¿Qué tienes que hacer entonces? dado que tienes un modelo muchos a muchos (es decir un doctor puede tener muchas especialidades y una especialidad puede tenerla muchos doctores), cambias a un modelo con tres tablas, supongamos que Hugo es doctor y tiene una especialidad en pediatría, su hermano Paco es doctor y tiene una especialidad en pediatría y otra en cardiología, Luis, el más pequeño tiene una especialidad en Medicina General, pero el Tío Donald es una eminencia y tiene especialidades en pediatría, medicina general, cardiología, neurología y geriatría... entonces, tu modelo sería así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
mysql> SELECT * FROM doctores;
+-----------+--------+
| id_doctor | nombre |
+-----------+--------+
|         1 | Hugo   |
|         2 | Paco   |
|         3 | Luis   |
|         4 | Donald |
+-----------+--------+
4 rows in set (0.00 sec)
 
mysql> SELECT * FROM especialidades;
+-----------------+------------------+
| id_especialidad | especialidad     |
+-----------------+------------------+
|               1 | Pediatría        |
|               2 | Cardiología      |
|               3 | Medicina General |
|               4 | Neurología       |
|               5 | Geriatría        |
+-----------------+------------------+
5 rows in set (0.02 sec)
 
mysql> SELECT * FROM doctores_especialidades;
+------------------------+-----------+-----------------+
| id_doctor_especialidad | id_doctor | id_especialidad |
+------------------------+-----------+-----------------+
|                      1 |         1 |               1 |
|                      2 |         2 |               1 |
|                      3 |         2 |               2 |
|                      4 |         3 |               3 |
|                      5 |         4 |               1 |
|                      6 |         4 |               2 |
|                      7 |         4 |               3 |
|                      8 |         4 |               4 |
|                      9 |         4 |               5 |
+------------------------+-----------+-----------------+
9 rows in set (0.00 sec)

es decir, no importa si un doctor NO TIENE ESPECIALIDADES o si tiene muchas, el modelo de tablas soporta ambos casos... si mañana alguno de los doctores completa una nueva especialidad, simplemente se agrega un registro a la tabla de relaciones.

Si puedes cambiar tu modelo de tablas, hazlo y evita dolores de cabeza en el futuro, ahora bien, si no es posible cambiar tu modelo, para resolver tu pregunta original, puedes utilizar UNION's para obtener sólo las descripciones únicas, es decir, hacer algo así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> SELECT * FROM especialidades;
+------+------------+------------+----------+
| id   | esp1       | esp2       | esp3     |
+------+------------+------------+----------+
|    1 | Cardiologo | Ginecologo | Pediatra |
|    2 | Geriatra   | Ginecologo | General  |
|    3 | Ginecologo | Oncologo   | NULL     |
|    4 | General    | NULL       | NULL     |
+------+------------+------------+----------+
4 rows in set (0.00 sec)
 
mysql> SELECT DISTINCT especialidad
    -> FROM
    -> ( SELECT esp1 especialidad FROM especialidades
    ->   UNION
    ->   SELECT esp2 especialidad FROM especialidades
    ->   UNION
    ->   SELECT esp3 especialidad FROM especialidades
    -> ) T;
+--------------+
| especialidad |
+--------------+
| Cardiologo   |
| Geriatra     |
| Ginecologo   |
| General      |
| Oncologo     |
| NULL         |
| Pediatra     |
+--------------+
7 rows in set (0.02 sec)

Observa que también se genera un registro con NULL, si no quieres que se muestre, simplemente agrega un WHERE a la consulta.

Haz la prueba y nos comentas.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Distinct para tres campos mysql

Publicado por vanessa (4 intervenciones) el 07/06/2017 17:22:11
Hola buenos días
de antemano muchas gracias por tu pronta respuesta y sobre todo muchísimas garcías por tomarte un tiempo para poder ayudarme Leo
me disculparas pero se muy poco sobre este tema.

ok entonces a lo que entendí es que la primera solución seria crear 3 tablas una doctores otra especialidades y otra donde se se la asignaran a cada doctor el tipo de especialidad que tiene ??

me parece una excelente opción: pero por cuestiones del proyecto no me seria posible ese cambio pero lo tomare muy en cuenta para próximas consultas


para lo solución dos no me queda del todo claro,
tengo mi tabla que se llama ESPECIALIDAD y mis campos esp1 esp 2 y esp3 que es donde tengo las especialidades
a loq ue entendi

SELECT DISTINCT especialidad ( aqui le pides que tome los valores distintos de la tabla especialidad)
-> FROM
-> ( SELECT esp1 especialidad FROM especialidades ( aqui no me queda muy claro por que es esp1 especialidad from especialidades )


asi es como hice mi codigo pero queda cargando y no sale nada


1
2
3
4
5
6
7
8
$clavebuscadah=mysql_query(" SELECT DISTINCT especilaidad FROM
  ( SELECT esp1 FROM especilaidad
    UNION
   SELECT esp2  FROM especilaidad
    UNION
   SELECT esp3 FROM especilaidad )",$conexion)
 
	or die("Problemas en el select:".mysql_error());

nuevamente gracias por tu ayuda y valioso tiempo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Distinct para tres campos mysql

Publicado por vanessa (4 intervenciones) el 07/06/2017 18:09:20
Hola otra vez modificando el código que te había mencionado
quedo así.

1
2
3
4
5
6
7
8
$clavebuscadah=mysql_query("
   SELECT distinct esp1 FROM especialidad
    UNION
   SELECT distinct esp2 FROM especialidad
    UNION
   SELECT distinct esp3 FROM especialidad WHERE (idestado='2')" ,$conexion)
 
	or die("Problemas en el select:".mysql_error());

asi ya me logro funcionar
pero me salen con mucho espacios y al dar clic en una especialidad no me respeta el where y me saca lo de todos los estados


1
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Distinct para tres campos mysql

Publicado por leonardo_josue (1079 intervenciones) el 07/06/2017 18:38:00
Hola de nuevo, un comentario adicional sobre tu consulta:

1
2
3
4
5
SELECT distinct esp1 FROM especialidad
UNION
SELECT distinct esp2 FROM especialidad
UNION
SELECT distinct esp3 FROM especialidad WHERE (idestado='2')

en tu post dices esto:

1
al dar clic en una especialidad no me respeta el where

Este es un "problema" bastante común al utilizar los UNION's, el detalle es que el WHERE, tal como lo pones SÓLO APLICA A LA ÚLTIMA DE LAS CONSULTAS DEL UNION, tienes de dos sopas para hacer que el WHERE aplique a todo:

1. Poner el WHERE para cada SUBCONSULTA DEL UNION, es decir, hacer esto:

1
2
3
4
5
SELECT distinct esp1 FROM especialidad WHERE idestado='2'
UNION
SELECT distinct esp2 FROM especialidad WHERE idestado='2'
UNION
SELECT distinct esp3 FROM especialidad WHERE idestado='2'

2. Aplicas el WHERE A LA TABLA RESULTANTE, para esto, deberás poner en el SELECT también el campo por el que vas a filtrar:

1
2
3
4
5
6
7
8
SELECT DISTINCT alias_campo
FROM
( SELECT esp1 alias_campo, idestado FROM especialidad
  UNION
  SELECT esp2 alias_campo, idestado FROM especialidad
  UNION
  SELECT esp3 alias_campo, idestado FROM especialidad) alias_tabla
WHERE alias_tabla.idestado = '2'

Haz la prueba y nos comentas.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Distinct para tres campos mysql

Publicado por leonardo_josue (1079 intervenciones) el 07/06/2017 18:24:55
Hola de nuevo Vanessa:

Vamos por partes:

1
ok entonces a lo que entendí es que la primera solución seria crear 3 tablas una doctores otra especialidades y otra donde se se la asignaran a cada doctor el tipo de especialidad que tiene ??

Esto es correcto, este tipo de modelos es la base del modelo Entidad-Relación en base de datos, por un lado tienes tablas CATALOGOS con la información "principal" sin duplicados, (es decir, con esto automáticamente solucionarías tu problema original), la tercer tabla es una tabla de RELACIONES y como su nombre lo indica, guarda los registros de cómo se relacionan las tablas catalogos... con los datos de ejemplo, observa detenidamente la tabla de relaciones para el caso del Dr. DONALD, (id_doctor = 4);

1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT * FROM doctores_especialidades WHERE id_doctor = 4;
+------------------------+-----------+-----------------+
| id_doctor_especialidad | id_doctor | id_especialidad |
+------------------------+-----------+-----------------+
|                      5 |         4 |               1 |
|                      6 |         4 |               2 |
|                      7 |         4 |               3 |
|                      8 |         4 |               4 |
|                      9 |         4 |               5 |
+------------------------+-----------+-----------------+
5 rows in set (0.00 sec)

Observa que para cada especialidad que tiene, SE AGREGA UN REGISTRO A LA TABLA... y aquí no hay límite, si un DR, tuviera 15 especialidades, entonces en la tabla de relaciones habría 15 REGISTROS (¿se entiende?). Para ampliar este tema podrías leer algún manual de Diseño de BD's o del Modelo Entidad-Relación.

Ahora bien, pasando a la solución, creo que te estás confundiendo con los nombres de los objetos y los ALIAS que estoy manejando... es posible que solo hayas copiado y pegado la solución sin observar realmente qué hacía cada cosa... además tienes un error de "dedo", ya que en tu consulta, estás poniendo tu tabla como especilaidad que no es lo mismo que especialidad.

Para empezar, en mi ejemplo la tabla se llama ESPECIALIDADES (es una buena práctica manejar los nombres de tablas en plural) y lo que hago es intenta es "simular" el primer modelo, es decir, crear un CATALOGO DE ESPECIALIDADES a partir de la información de las tres tablas:

Observa esto:

1
2
3
4
5
6
7
8
9
10
mysql> SELECT * FROM especialidades;
+------+------------+------------+----------+
| id   | esp1       | esp2       | esp3     |
+------+------------+------------+----------+
|    1 | Cardiologo | Ginecologo | Pediatra |
|    2 | Geriatra   | Ginecologo | General  |
|    3 | Ginegoloco | Oncologo   | NULL     |
|    4 | General    | NULL       | NULL     |
+------+------------+------------+----------+
4 rows in set (0.01 sec)

Lo se hace con el UNION es crear una tabla "virtual" con una sola columna, que contenga la información de las tres columnas de tu tabla:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql> SELECT esp1 FROM especialidades
    -> UNION ALL
    -> SELECT esp2 FROM especialidades
    -> UNION ALL
    -> SELECT esp3 FROM especialidades;
+------------+
| esp1       |
+------------+
| Cardiologo |
| Geriatra   |
| Ginecologo |
| General    |
| Ginecologo |
| Ginecologo |
| Oncologo   |
| NULL       |
| Pediatra   |
| General    |
| NULL       |
| NULL       |
+------------+
12 rows in set (0.00 sec)

El alias en realidad no es "importante" pero si es significativo, cuando haces un UNION, si los nombres de los campos NO SON IGUALES, por defecto asigna el nombre del primer UNION a la tabla resultante, observa en este ejemplo que la columna resultante tiene el nombre de ESP1

En mi ejemplo hago esto:

1
SELECT esp1 especialidad FROM especialidades

lo único que hago es crear un ALIAS para cambiar el nombre de ESP1 a especialidad, lo mismo pasa con ESP2 y ESP3, es decir "estandarizo" un mismo nombre para los tres campos, sea que uses alias o no, debes tener en cuenta el nombre del campo para la siguiente parte:

Una vez que tienes esta tabla "virtual" lo que haces es seleccionar los registros DISTINTOS, mediante una subconsulta:

1
2
3
SELECT DISCTINCT tu_alias_o_tu_nombre_de_campo
FROM
(aquí pones la subconsulta con los UNION) T

MUCHO OJO: observa que después del paréntesis que cierra la subconsulta pongo una T, esto es también UN ALIAS para la tabla resultante, puedes poner el alias que quieras, pero debes ponerlo, (en tu ejemplo no pones este alias)

entonces, tu consulta CON TUS NOMBRES podría quedar así:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> SELECT DISTINCT alias_campo
    -> FROM
    -> ( SELECT esp1 alias_campo FROM especialidad
    ->   UNION ALL
    ->   SELECT esp2 alias_campo FROM especialidad
    ->   UNION ALL
    ->   SELECT esp3 alias_campo FROM especialidad ) alias_tabla;
+-------------+
| alias_campo |
+-------------+
| Cardiologo  |
| Geriatra    |
| Ginecologo  |
| General     |
| Oncologo    |
| NULL        |
| Pediatra    |
+-------------+
7 rows in set (0.00 sec)

Observa que en el SELECT externo PONGO EL ALIAS QUE LE ESTOY ASIGNANDO AL CAMPO EN LOS UNION'S (en este campo "alias_campo") y observa que al después del paréntesis le asigno un ALIAS A LA TABLA RESULTANTE (en este caso "alias_tabla")

Finalmente, como recomendación, cuando ejecutes alguna consulta así, hazlo directamente desde una consola de MySQL o desde el Workbench, para que sepas qué errores de SQL tiene la consulta y nos los confundas con errores de PHP o de cualquier lenguaje con el que estés programando.

Haz la prueba y nos comentas.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Distinct para tres campos mysql

Publicado por vanessa (4 intervenciones) el 07/06/2017 22:31:10
Hola leo
Muchas gracias por toda la ayuda y el tiempo invertido en estas preguntas
ya me quedo mas claro el por que de los alias y de y función de UNION

y te agradezco enormemente tu ayuda y la explicación estuvo excelente en efecto ya se resolvio el problema tal cual me lo explicaste
una vez mas muchas gracias

el código quedo de la siguiente manera:

1
2
3
4
5
6
7
8
9
10
11
12
SELECT DISTINCT especial
FROM
( SELECT esp1 especial, idestado FROM especialidad
  UNION
  SELECT esp2 especial, idestado FROM especialidad
  UNION
  SELECT esp3 especial, idestado FROM especialidad) tbl
WHERE tbl.idestado = '2'" ,$conexion)

	or die("Problemas en el select:".mysql_error());
	  

saludos y hasta pronto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar