epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
Hola a todos... tengo 2 tablas en la bd , ambas relacionadas por el rut.:

1.- pacientes
2.- seguimiento

En la tabla "pacientes" tengo 1 registro con el Rut "11111111-1" y en la tabla "seguimiento" tengo 2 registros con el mismo Rut "11111111-1" (ya que un paciente puede tener mas de un seguimiento) y si hago la consulta:

SELECT * FROM pacientes, seguimiento WHERE pacientes.rut=seguimiento.rut

Me trae datos duplicados del paciente "11111111-1" ya que esta 2 veces en la tabla "seguimiento", lo que quiero hacer es que me lo traiga solo una vez.


En PHP tengo:
$sql2 = "SELECT * FROM pacientes, seguimiento WHERE pacientes.rut=seguimiento.rut";
$resultado2 = $mysqli->query($sql2) or trigger_error($mysqli->error);

y mas abajo una tabla:
<div class="row table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Rut</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Email</th>
<th>Telefono</th>
<th>Tipo Diabetes</th>
<th>Fecha Ingreso</th>
<th>Fecha Educación</th>
<th></th>
<th></th>
</tr>
</thead>

<tbody>
<?php while($row2= $resultado2->fetch_array(MYSQLI_ASSOC)) { ?>
<tr>
<td><?php echo $row2['rut']; ?></td>
<td><?php echo $row2['nombres']; ?></td>
<td><?php echo $row2['apellidos']; ?></td>
<td><?php echo $row2['email1']; ?></td>
<td><?php echo $row2['telefono1']; ?></td>
<td><?php echo $row2['tipo_diabetes']; ?></td>
<td><?php echo $row2['f_ing_prog']; ?></td>
<td><?php echo $row2['f_educacion']; ?></td>
<td><a href="modificar.php?rut=<?php echo $row2['rut']; ?>"><span class="glyphicon glyphicon-pencil" title="Editar Registro"></span></a></td>
<td><a href="seguimiento.php?rut=<?php echo $row2['rut']; ?>"><span class="glyphicon glyphicon-plus" title="Agregar Seguimiento"></span></a></td>
<td><a href="#" data-href="eliminar.php?rut=<?php echo $row2['rut']; ?>" data-toggle="modal" data-target="#confirm-delete" title="Eliminar Registro"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>



El Campo "Fecha Educación (f_educacion)" pertenece a la tabla "seguimiento", y todos los demas a la table "pacientes" de la bd.


Si me puede echar una manito... gracias!
 

Supermanco

Miembro Activo
Se incorporó
15 Abril 2021
Mensajes
25
Le estas diciendo que traiga todo de las dos tablas (pues ese SELECT * lo hace sobre dos tablas), ve que hay un match dos veces en Seguimiento y lo va a traer dos veces. No se si podes usar SELECT DISTINCT pacientes.* (o las columnas que precises) y de esa forma quedan excluidas las repeticiones. Estoy suponiendo que en tu consulta solo te interesa mostrar datos de Pacientes.

No se si en este caso te permiten usar operaciones de JOIN, de esa forma en el FROM usas solo una tabla pero le decis que vincule los datos a través de la clave con la otra tabla, sin que esté involucrada directamente en el SELECT).
 
Upvote 0

Lordnet

Autoridad Ancestral de Transacciones
Se incorporó
11 Junio 2004
Mensajes
2.231
una parche que puedes hacer es que que la segunda tabla la cambies por una función de agregación.

SQL:
select pacientes.rut, count(seguimiento.rutseg) from pacientes
inner join seguimiento on pacientes.rut=seguimiento.rutseg

te traerá un registro por rut, y contará los seguimientos si es que hay mas de uno.



sin contar sería
SQL:
select pacientes.rut from pacientes
inner join seguimiento on pacientes.rut=seguimiento.rutseg
group by pacientes.rut
 
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
Le estas diciendo que traiga todo de las dos tablas (pues ese SELECT * lo hace sobre dos tablas), ve que hay un match dos veces en Seguimiento y lo va a traer dos veces. No se si podes usar SELECT DISTINCT pacientes.* (o las columnas que precises) y de esa forma quedan excluidas las repeticiones. Estoy suponiendo que en tu consulta solo te interesa mostrar datos de Pacientes.

No se si en este caso te permiten usar operaciones de JOIN, de esa forma en el FROM usas solo una tabla pero le decis que vincule los datos a través de la clave con la otra tabla, sin que esté involucrada directamente en el SELECT).
por DISTINCT no funciona, pero quizas por el JOIN... tendre que probar... gracias
 
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
una parche que puedes hacer es que que la segunda tabla la cambies por una función de agregación.

SQL:
select pacientes.rut, count(seguimiento.rutseg) from pacientes
inner join seguimiento on pacientes.rut=seguimiento.rutseg

te traerá un registro por rut, y contará los seguimientos si es que hay mas de uno.



sin contar sería
SQL:
select pacientes.rut from pacientes
inner join seguimiento on pacientes.rut=seguimiento.rutseg
group by pacientes.rut

Siii, ese sirve , agregue solamente el segundo código y al parecer funciono.

select pacientes.rut from pacientes
inner join seguimiento on pacientes.rut=seguimiento.rut
group by pacientes.rut
 
Upvote 0

Lordnet

Autoridad Ancestral de Transacciones
Se incorporó
11 Junio 2004
Mensajes
2.231
el tema es que mencionas que te traes la fecha de educación
si el paciente tiene mas de un registro, cuál te debes traer supuestamente.
 
Upvote 0

el_dva

Capo
Se incorporó
23 Noviembre 2009
Mensajes
203
Estimado, me costo entender lo que querías, pero como pusiste el código, asumo que quieres traer solo a los pacientes que tienen algún seguimiento, para eso no necesitan JOIN, solo debes hacer la siguiente query:

SQL:
SELECT *
FROM pacientes
WHERE pacientes.rut IN ( SELECT seguimiento.rut FROM seguimiento)
 
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
Estimado, me costo entender lo que querías, pero como pusiste el código, asumo que quieres traer solo a los pacientes que tienen algún seguimiento, para eso no necesitan JOIN, solo debes hacer la siguiente query:

SQL:
SELECT *
FROM pacientes
WHERE pacientes.rut IN ( SELECT seguimiento.rut FROM seguimiento)

Hola @el_dva , en realidad es un listar en la pagina principal que me debe traer a todos los pacientes, pero solo una vez. Como algunos tenían mas de un seguimiento, me estaba trayendo mas de un registro por paciente. Con el código de @Lordnet me funciono.
 
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
@Lordnet, al poner esa linea de INNER JPOIN me dejo de funcionar un buscar que tenia... si lo dejo como esta ahii, el buscar funciona, pero el campo de seguimiento no, si lo dejo como me lo indicas tu, me muestra todos los campos y una sola vez, pero el buscar no hace nada :S

Sabes como podría incorporar ese $where en la linea del inner para que vuelva a funcionar??

<?php
require 'conexion.php';
$user = $_SESSION['nombredelusuario'];
$where = "";
if(!empty($_POST))
{
$valor = $_POST['rut'];
if(!empty($valor)){
$where = "WHERE rut LIKE '%$valor'";
}
}
$sql = "SELECT * FROM pacientes $where";

$resultado = $mysqli->query($sql) or trigger_error($mysqli->error);

# $sql1 = "SELECT * FROM pacientes INNER JOIN seguimiento ON pacientes.rut=seguimiento.rut GROUP BY pacientes.rut";
# $resultado1 = $mysqli->query($sql1) or trigger_error($mysqli->error);
?>
<html lang="es">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/bootstrap-theme.css" rel="stylesheet">
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>

<body>

<div class="container">
<div class="row">
<h2 style="text-align:center">FORMULARIO</h2>
</div>

<div class="row">
<a href="nuevo.php" class="btn btn-primary">Nuevo Registro</a>

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
<b>Rut: </b><input type="text" id="rut" name="rut" />
<input type="submit" id="enviar" name="enviar" value="Buscar" class="btn btn-info" />
<a href="salir.php" class="btn btn-primary">Logout</a>
</form>
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
<a href="excel.php" class="btn btn-info">Descargar Excel</a>
</form>
</div>

<br>

<div class="row table-responsive">
<table class="table table-striped">
<!-- <table data-toggle="table" data-click-to-select="true" data-pagination="true" data-page-list="[5, 10, 15, 20]" data-height="340" data-search="true" class="table-hover table-responsive" id="tableRoomList"> -->
<thead>
<tr>
<th>Rut</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Email</th>
<th>Telefono</th>
<th>Tipo Diabetes</th>
<th>Fecha Ingreso</th>
<th>Fecha Educación</th>
<th></th>
<th></th>
</tr>
</thead>

<tbody>
<?php while($row2= $resultado->fetch_array(MYSQLI_ASSOC)) { ?>
<tr>
<td><?php echo $row2['rut']; ?></td>
<td><?php echo $row2['nombres']; ?></td>
<td><?php echo $row2['apellidos']; ?></td>
<td><?php echo $row2['email1']; ?></td>
<td><?php echo $row2['telefono1']; ?></td>
<td><?php echo $row2['tipo_diabetes']; ?></td>
<td><?php echo $row2['f_ing_prog']; ?></td>
<td><?php echo $row2['f_educacion']; ?></td>
<td><a href="modificar.php?rut=<?php echo $row2['rut']; ?>"><span class="glyphicon glyphicon-pencil" title="Editar Registro"></span></a></td>
<td><a href="seguimiento.php?rut=<?php echo $row2['rut']; ?>"><span class="glyphicon glyphicon-plus" title="Agregar Seguimiento"></span></a></td>
<td><a href="#" data-href="eliminar.php?rut=<?php echo $row2['rut']; ?>" data-toggle="modal" data-target="#confirm-delete" title="Eliminar Registro"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
...
..
.
 
Upvote 0

el_dva

Capo
Se incorporó
23 Noviembre 2009
Mensajes
203
Hola @el_dva , en realidad es un listar en la pagina principal que me debe traer a todos los pacientes, pero solo una vez. Como algunos tenían mas de un seguimiento, me estaba trayendo mas de un registro por paciente. Con el código de @Lordnet me funciono.

La query de @Lordnet técnicamente es mas lenta al traer todos los registros de seguimiento y después agruparlos por group, imagina a 1000 pacientes con 100 seguimiento cada uno, la query traeria 100.000 registros para agruparlos, por el group. si quieres traer todos pacientes que tienen al menos un seguimiento usa in o exists.
 
Upvote 0

Lordnet

Autoridad Ancestral de Transacciones
Se incorporó
11 Junio 2004
Mensajes
2.231
el código de @el_dva debería servirte, ahi no requieres inner join

hice el fiddle nuevamente y si funciona

y este código funciona sin inner join

SQL:
select pacientes.rut from pacientes
where pacientes.rut in (select seguimiento.rutseg from seguimiento)

recomendación
NO usar select * , indicar explícitamente los campos que necesitas rescatar
No usar like a menos que quieras que entregue resultados con fracciones de rut, si no que la busqueda sea explícita.

por lo que entendí de tu código, le dejas un condicional, que te traiga todos los registros si es que no especifican el rut. pero si te lo colocan, que te traiga el rut que necesitas, aplicando un WHERE.

prueba con
PHP:
$campo= "";
if(!empty($_POST))
{
$valor = $_POST['rut'];
if(!empty($valor)){
$campo= "AND rut LIKE '%$valor'";
}
}
$sql = "SELECT * FROM pacientes where pacientes.rut in (select seguimiento.rutseg from seguimiento) $campo";
$resultado = $mysqli->query($sql) or trigger_error($mysqli->error);

 
Upvote 0

ricm

Se incorporó
28 Agosto 2005
Mensajes
7.590
No se si entendí bien la pregunta o no, pero no te bastaba hacer limit 1?
 
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
el código de @el_dva debería servirte, ahi no requieres inner join

hice el fiddle nuevamente y si funciona

y este código funciona sin inner join

SQL:
select pacientes.rut from pacientes
where pacientes.rut in (select seguimiento.rutseg from seguimiento)

recomendación
NO usar select * , indicar explícitamente los campos que necesitas rescatar
No usar like a menos que quieras que entregue resultados con fracciones de rut, si no que la busqueda sea explícita.

por lo que entendí de tu código, le dejas un condicional, que te traiga todos los registros si es que no especifican el rut. pero si te lo colocan, que te traiga el rut que necesitas, aplicando un WHERE.

prueba con
PHP:
$campo= "";
if(!empty($_POST))
{
$valor = $_POST['rut'];
if(!empty($valor)){
$campo= "AND rut LIKE '%$valor'";
}
}
$sql = "SELECT * FROM pacientes where pacientes.rut in (select seguimiento.rutseg from seguimiento) $campo";
$resultado = $mysqli->query($sql) or trigger_error($mysqli->error);


Si, ahí me busca, pero el campo "f_educacion" que es de la tabla "seguimiento" no me lo trae.

(select seguimiento.rutseg from seguimiento) -> porque se le agrega ese "seg" al final de "seguimiento.rutseg" ?? , si lo dejo asi, me tira error:

Notice: Unknown column 'seguimiento.rutseg' in 'field list' in /opt/lampp/htdocs/prueba/todo.php on line 23

Si le saco ese "seg" me funciona la pagina... pero no me trae la fecha: ACABO DE VER LA PAGINA CON EL COD QUE CREASTE... TENDRE QUE CAMBIAR LA VAR RUT EN LA TABLA SEGUIMIENTO A RUTSEG ?

Notice: Undefined index: f_educacion in /opt/lampp/htdocs/prueba/todo.php on line 85

---------------------------------------------

Tabla "pacientes"
rut
nombres
apellidos
email1
telefono1
tipo_diabetes
f_ing_prog

Tabla "seguimiento"
f_educacion


1652712468072.png
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.872
Oye @epic , ¿qué esperas que devuelva la consulta? ¿Solamente los datos del paciente? Porque si la cruzas con "segumiento" inevitablemente tendrás dos registros. ¿Por qué la cruzas con seguimiento? ¿Esperas validar algo de ahí?
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.872
Estimado, me costo entender lo que querías, pero como pusiste el código, asumo que quieres traer solo a los pacientes que tienen algún seguimiento, para eso no necesitan JOIN, solo debes hacer la siguiente query:

SQL:
SELECT *
FROM pacientes
WHERE pacientes.rut IN ( SELECT seguimiento.rut FROM seguimiento)


Ah ya, si lo que quieres es obtener los nombres (y solamente los nombres) de los pacientes que han tenido segumiento, la opción más eficiente es la que menciona @el_dva .

No se si funciona en MySql pero prueba esto

SQL:
SELECT *
FROM pacientes p
WHERE exists ( SELECT 1 FROM seguimiento s where s.rut = p-rut )
 
Upvote 0

ricm

Se incorporó
28 Agosto 2005
Mensajes
7.590
Si, ahí me busca, pero el campo "f_educacion" que es de la tabla "seguimiento" no me lo trae.

(select seguimiento.rutseg from seguimiento) -> porque se le agrega ese "seg" al final de "seguimiento.rutseg" ?? , si lo dejo asi, me tira error:

Notice: Unknown column 'seguimiento.rutseg' in 'field list' in /opt/lampp/htdocs/prueba/todo.php on line 23

Si le saco ese "seg" me funciona la pagina... pero no me trae la fecha: ACABO DE VER LA PAGINA CON EL COD QUE CREASTE... TENDRE QUE CAMBIAR LA VAR RUT EN LA TABLA SEGUIMIENTO A RUTSEG ?

Notice: Undefined index: f_educacion in /opt/lampp/htdocs/prueba/todo.php on line 85

---------------------------------------------

Tabla "pacientes"
rut
nombres
apellidos
email1
telefono1
tipo_diabetes
f_ing_prog

Tabla "seguimiento"
f_educacion


Ver adjunto 23576
Donde dice rutseg es rut solamente.
Si no trae f educación es por que no esta en el select.
 
Última modificación:
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.872
Está peludo agregar f_educacion ahí sin mandar el costo de la consulta a la cresta. La manera elegante es llamar solamente una vez a la tabla seguimiento utilizando funciones tipo dense_rank pero también está el método bruto que es llamarla dos veces o incluso hacer una subquery.


Código:
SELECT p.rut, p.nombres, p.apellidos, p.email1, p.telefono1, p.tipo_diabetes, p.f_ing_prog,
       MAX(s.f_educacion) KEEP(DENSE_RANK LAST ORDER BY s.id_seguimiento)
FROM pacientes p
left join seguimiento s where s.rut = p.rut
group by p.rut, p.nombres, p.apellidos, p.email1, p.telefono1, p.tipo_diabetes, p.f_ing_prog

Update, me habían faltado los group by

Ojo

Dado que para un rut puede haber más de un f_educacion distinto, estoy asumiendo que el último f_educacion es el que vale.




Cáchate esto


 
Última modificación:
Upvote 0

epic

Pro
Se incorporó
11 Febrero 2007
Mensajes
846
Esos son los campos que estoy mostrando en el index (un solo registro por rut) y en "Fecha Educación" debería mostrar las fechas que podrían ser como máximo 3 o mostrar solamente la ultima.

$campo= "";
if(!empty($_POST))
{
$valor = $_POST['rut'];
if(!empty($valor)){
$campo= "AND rut LIKE '%$valor'";
}
}
$sql = "SELECT * FROM pacientes where pacientes.rut in (select seguimiento.rut from seguimiento) $campo";
$resultado = $mysqli->query($sql) or trigger_error($mysqli->error);


1652724448701.png


Tabla "pacientes"
rut
nombres
apellidos
email1
telefono1
tipo_diabetes
f_ing_prog

Tabla "seguimiento"
f_educacion

1652724503590.png
 
Upvote 0
Subir