Comunidad de diseño web y desarrollo en internet online

Consulta de una novata

Citar            
MensajeEscrito el 06 Jun 2011 02:41 am
Hola, me estoy volviendo loca para sacar una consulta de php.

Tabla 1: Líquido: agua, leche, vino, aceite
Tabla 2: Líquido/Litros (agua,3) (vino,2) (leche,1)

Y quiero añadir a la Tabla 2 los líquidos que no existen en ella, con cantidad 0.

En este caso solo habría que añadir (aceite,0)

Consulta final: (agua,3) (vino,2) (leche,1) (aceite,0)

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 06 Jun 2011 05:31 am
Hola!, lo que deberías hacer es realizar una conexión a la base de datos para luego ejecutar tu consulta, no te puedo dar exactamente la query que necesitás porque no conozco la estructura de tu BD, pero sería algo así:

Código PHP :

class Tablas{

$server = "localhost";
$user = "root";
$pass = "";
$dbname = "nombreBD";
   
    function insertar($datos){
                $link= mysql_connect($server,$user,$pass); //conectás a la base
      mysql_select_db($dbname); //elegís la base
               $query = "INSERT INTO tabla2(idLiquido,litros) VALUES('".$datos->idLiquido."', 
'".$datos->cantidad."')";
                mysql_query($query); //ejecutás tu query en SQL
              mysql_close($link); //cerrás tu conexión a la BD.
                                     }
}



Luego, instanciás un objeto de la clase, y llamás a la función, enviando el objeto como parámetro.

Estaría bueno que pongas el código que habías intentado hacer, para ayudarte un poco más. Saludos!

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 06 Jun 2011 11:51 am
Gracias por tu respuesta rápida.

Quizás no me expliqué bien del todo.
Lo que quiero no es crear una tabla.
Quiero hacer una consulta.
O sea, select * ...

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 06 Jun 2011 04:04 pm
para un select necesitamos saber cuales la estrucutar de tu db , si no estaremos jugando a las adivinanzas :)

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 06 Jun 2011 05:28 pm
Pero si ya puse la extructura, a ver:

Tabla 1: Con un solo campo, "Líquido" de tipo texto.
Tabla 2: Con dos campos; "Líquido" de tipo texto, y "Litros" de tipo numérico.

Necesito un solo select.

A ver si ahora me he explicado mejor, que me vuelvo loquita.

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 06 Jun 2011 05:46 pm

mariahh escribió:

Pero si ya puse la extructura, a ver:

Tabla 1: Con un solo campo, "Líquido" de tipo texto.
Tabla 2: Con dos campos; "Líquido" de tipo texto, y "Litros" de tipo numérico.

Necesito un solo select.

A ver si ahora me he explicado mejor, que me vuelvo loquita.


Necesitás un SELECT, o un INSERT? SELECT es para traer datos de la base de datos, y el INSERT para insertar datos.

Para el insert, es lo que te puse en el post anterior, de todas formas te escribo nuevamente la query:
$query= INSERT INTO tabla2(liquido,litros) VALUES('".$liquidoAAgregar."', '".$cantidadAAgregar."')";

Para la estructura de tu base, tendrías que tener un campo identificador de la tabla, un id que sea una primary key autoincremental, así identificarías cada row .

La tabla 2 debería tener una relación la tabla 1, entonces en vez de ingresar el texto del líquido, ingresás el ID de la tabla 1, en el campo líquido de la tabla 2 (que debería ser un int)

Para el caso del select:

$q ="SELECT * FROM tabla2";

Espero haber sido claro, cualquier cosa, pregunte! Saludos.

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 06 Jun 2011 07:06 pm
cuandom te dije que estructura me referia a una sentencia sql para crear las tablas o si no un representacion grafica jeje :) asi es mas facil.
bueno tienes esta estructura segun entiendo:

Código :

++ tabla_1++
+ liquido  +
+----------+
+  agua    +
+  leche   +
+  vino    +
+  aceite  +
++++++++++++

+++++  tabla_2  +++++
+ liquido  + litros +
+----------+--------+
+  agua    +   3    +
+  vino    +   2    +
+  leche   +   1    +
+++++++++++++++++++++

y tu al hacer un select quieres obtener los datos de la tabla1 con los valores de la tabla 2 pero si estos no estan en dicha tabla llenarlos con 0

bueno primero dime es esa tu estrucutra? ya que si es asi yo diria que la necesidad de tener 2 tablas casi identicas no es nada productivo ya que sencillamente podrias hacer eso con la tabla2 simplemente
en sql hay lo que se llama valores por default al momento de agregar un nueva celda si esta no es explicitamente insertada y esta configurada con su valor por defecto esta misma se llena con dicho valor
ahora lo que quieres hacer
en la sentencia sql seria

Código MySQL :

SELECT t1.liquido, t2.litros
FROM tabla_1 AS t1
LEFT OUTER JOIN tabla_2 AS t2
            ON t1.liquido = t2.liquido
LIMIT 0 , 30


no te retornara 0 si no NULL ya eso lo puedes interpretar con php con la funcion is_null para que muestre un 0 usar un cast (int)

si alguien quiere experimentar con joisn dejo el sql q utilce

Código MySQL :

CREATE TABLE IF NOT EXISTS `tabla_1` (
  `liquido` varchar(255) NOT NULL,
  UNIQUE KEY `liquido` (`liquido`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `tabla_1` (`liquido`) VALUES
('aceite'),
('agua'),
('leche'),
('vino');

-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tabla_2` (
  `liquido` varchar(255) NOT NULL,
  `litros` int(13) NOT NULL,
  UNIQUE KEY `liquido` (`liquido`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `tabla_2` (`liquido`, `litros`) VALUES
('agua', 2),
('leche', 5);

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 06 Jun 2011 08:49 pm
A ver, quise reducir el problema, pero veo que una servidora no avanza, por eso pongo el problema real:

La tabla [Productos] está compuesta de "Indice" tipo autonumérico (clave principal), y "Producto" tipo texto.
1,Mesa
2,Silla
3,Sofa
5,Mueble
El Indice 4 no existe, se ha borrado el producto a votar

La tabla [Votaciones] está compuesta de "Indice" tipo autonumérico (clave principal), "IP" tipo texto, y "Producto" tipo número.
Indice,IP,Producto
1,1,1 (registro desechable porque la IP 1 ha votado más tarde al producto 3)
2,1,2 (registro desechable porque la IP 1 ha votado más tarde al producto 3)
3,1,3 La IP 1 vota por Sofa
4,2,1 La IP 2 vota por Mesa
5,3,1 La IP 3 vota por Mesa
6,4,5 La IP 4 vota por Mueble
Nadie vota por Silla

Entonces el select tiene que dar:
Votos,Producto,Indice
2,Mesa,1
1,Sofa,3
1,Mueble,5
0,Silla,2

Con esto:
SELECT MAX(Votaciones.Indice) FROM Votaciones GROUP BY Votaciones.IP
Consigo 3,4,5,6 justo los registros que deseo

Asi que hago esto:
SELECT Count(Votaciones.Producto) AS Votos, Productos.Producto, Productos.Indice
FROM Votaciones INNER JOIN Productos ON Votaciones.Producto=Productos.Indice
WHERE Votaciones.Indice IN (SELECT MAX(Votaciones.Indice) FROM Votaciones GROUP BY Votaciones.IP)
GROUP BY Productos.Producto, Productos.Indice

Y consigo esto:
Votos,Producto,Indice
2,Mesa,1
1,Sofa,3
1,Mueble,5

Ya solo falta añadir:
0,Silla,2

Si hago: UNION SELECT 0, Productos.Producto, Productos.Indice from Productos
se añaden todos los productos, pero yo solo quiero: 0,Silla,2

Espero que se me entienda ahora, gracias eh!

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 07 Jun 2011 05:24 am
Disculpá que no te haga la prueba yo, ando corto de tiempo para armar la BD y hacer probar queries :P , pero por lo que veo, lo podés solucionar con un RIGHT JOIN en vez de un INNER JOIN, lo que te va a hacer es traerte TODOS los campos que se encuentren en tabla de la derecha (en la de productos, en la que tenés a silla), y además los datos que se unen por la cláusula join normal, entonces así traerías también a silla, que vendría con los datos nulos (puesto que no tiene una fila asociada en la otra tabla) .
P.D: Depende de la ubicación que le des a la tabla Productos, es un RIGHT JOIN o un LEFT JOIN, cumplen la misma función, sólo que uno trae TODOS los de la izquierda, y el otro TODOS los de la derecha.

Avisá qué tal te fue! Saludos!

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 07 Jun 2011 12:32 pm
Nada, no lo consigo, ayuda, plis, a esta novata.

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 08 Jun 2011 05:20 am
Hola! Acá te dejo la query, si bien hay mejores formas de hacerla, tal como el uso de vistas, agregar índices y etc... esta es tu query:

SELECT COUNT(Votaciones.`Producto`) AS Votos, Productos.Indice, Productos.Producto
FROM Votaciones INNER JOIN Productos ON Votaciones.Producto=Productos.Indice
WHERE Votaciones.Indice AND `votaciones`.`Indice`IN
(SELECT MAX(Votaciones.Indice) FROM Votaciones GROUP BY Votaciones.IP)
GROUP BY productos.`producto`

UNION

SELECT 0, productos.* FROM `productos` WHERE productos.`Indice`
NOT IN (SELECT MAX(Votaciones.`Producto`) FROM Votaciones GROUP BY Votaciones.IP )

Si te tira algún error, revisá la sintaxis :P . Con esa query obtenés el resultado que esperabas.
Saludos y espero haberte sido de ayuda !

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 08 Jun 2011 08:01 pm
Graciaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassss.

Te mando un beso muy grande, lo has conseguido!!!!

Has acabado lo que empecé y no pude terminar.

Eres genial!!!

Tuve que corregir algo la sintaxis, pero bueno:
En el primer select hay que agrupar también por Productos.Indice.
En el segundo select no se puede poner productos.*, es Productos.Producto y Productos.Indice.
Y en el primer select no entendí por que pones:
Votaciones.Indice AND `votaciones`.`Indice`IN
Votaciones.Indice sobra, parece que funciona solo con AND `votaciones`.`Indice`IN

Pero bueno, detalles, lo bueno es que lo has conseguido, donde se te pueden dar mil puntos?

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 08 Jun 2011 10:45 pm
Parece que me he precipitado con las gracias.

Al final pones:
SELECT MAX(Votaciones.`Producto`) FROM Votaciones GROUP BY Votaciones.IP

Con lo cual obtienes los productos 3, 1, 1 y 5.
Pero no hay que obtener el producto con número más grande, sinó el producto con indice más alto, o sea, el que se votó más tarde de cada IP.

Te ha dado resultado pero de chiripa.
Si el primer registro de votaciones fuera el 5, te saldría: 5, 1, 1 y 5.
Con lo cual no constaría el producto 3 como votado y se añadiría a la lista otra vez, esta vez con 0 votos.

Sigo embozada con el mismo problema, a ver si alguien me saca de esta...

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 09 Jun 2011 07:06 am
Pensé que sólo la querías para esas tandas de datos, puesto que querías hacer un UNION con el campo 2, por eso la otra query no funciona :P, veo que entendí mal una vez más jaja. Igual, no entendí exactamente lo que explicaste de cambiar el id, pero sí comprendí a lo que apuntabas, y creo que acá está la solución:

Como te puse anteriormente, lo mejor es hacer vistas, y es lo que vamos a usar: Creás una vista con la primer query, antes del UNION, Yo la llamé view_votados :

Código MySQL :

select
count(`votaciones`.`indice`) AS `Votos`,
`productos`.`indice` AS `idProducto`
from
(`votaciones` join `productos` on((`votaciones`.`Producto` = `productos`.`indice`)))
where
(`votaciones`.`indice` in (
select
max(`votaciones`.`indice`)
from
`votaciones`
group by
`votaciones`.`ip`))
group by
`productos`.`producto`


Luego, vamos a agregar a la vista, los productos sin votos:

Código MySQL :

SELECT `view_votados`.`Votos`, `productos`.`producto`, `productos`.`indice` FROM `view_votados`
RIGHT OUTER JOIN `productos` ON `view_votados`.`idProducto` = `productos`.`indice`
ORDER BY `view_votados`.`Votos` DESC

Esta query sí debería funcionarte bien jeje. Se simplifica mucho al usar una vista, puesto que ya los podés trabajar como una tabla unida, más simple y entendible.

Si por algún lado te tira error porque no reconoce un campo id o idProducto, es porque yo al crear la base preferí llamar Id a tu campo indice , y votaciones.idProducto al campo votaciones.producto .
Prueba la query y contá cómo te fue. Saludos!

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 09 Jun 2011 04:44 pm
En primer lugar gracias por tu dedicación.
Seguro que eso funciona, pero a ver.
Yo en un archivo de php hago un select y luego voy mostrando la tabla resultante de ese select.
Tu me pones dos selects.
En el segundo haces referencia a view_votados, que se supone que es el primero.
Donde asignas el nombre view_votados al primer select?
Como puedo poner dos selects en una sola instrucción de php mmm.

Yo hago:

$resultado = mysql_query("SELECT ...");
while($row = mysql_fetch_array($resultado))
{
Echo $row[ ...
}

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 09 Jun 2011 05:59 pm
Tenés que crear una vista en la base de datos, para la primer consulta (la que llamo view_votados).
Eso lo podés hacer desde tu administrador de base de datos, fijate que vas a tener una parte que dice View , y ahí ponés agregar view, y ahí pegás el select, o bien, desde una query directamente:

Código MySQL :

CREATE VIEW view_votados AS
select

count(`votaciones`.`indice`) AS `Votos`,

`productos`.`indice` AS `idProducto`

from

(`votaciones` join `productos` on((`votaciones`.`Producto` = `productos`.`indice`)))

where

(`votaciones`.`indice` in (

select

max(`votaciones`.`indice`)

from

`votaciones`

group by

`votaciones`.`ip`))

group by

`productos`.`producto`

Esta query la ejecutás con tu administrador de base de datos (o desde php, es indistinto) una única vez (la query crea la vista , similar a una tabla).
Y luego, desde PHP, ya con la vista creada, lo único que llamás es a la segunda query :

Código MySQL :


SELECT `view_votados`.`Votos`, `productos`.`producto`, `productos`.`indice` FROM `view_votados`

RIGHT OUTER JOIN `productos` ON `view_votados`.`idProducto` = `productos`.`indice`

ORDER BY `view_votados`.`Votos` DESC


Te dejo el de mysql de las vistas:
Link de Vistas

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 09 Jun 2011 06:30 pm
Ese es el problema, no puedo alterar la base de datos ni hacer vistas.

Necesito uno o varios selects, lo que sea.

Tiene que haber alguna solución, me resisto a rendirme.

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 09 Jun 2011 07:08 pm
Parece una locura, pero igual encontré la solución yo misma:

SELECT COUNT(Votaciones.Producto) AS Votos, Productos.Producto, Productos.Indice
FROM Votaciones INNER JOIN Productos ON Votaciones.Producto=Productos.Indice
WHERE Votaciones.Indice IN (SELECT MAX(Indice) FROM Votaciones GROUP BY IP)
GROUP BY Productos.Producto, Productos.Indice
UNION SELECT 0, Productos.Producto, Productos.Indice from Productos
WHERE Productos.Indice NOT IN
(
SELECT Votaciones.Producto
FROM Votaciones INNER JOIN Productos ON Votaciones.Producto=Productos.Indice
WHERE Votaciones.Indice IN (SELECT MAX(Indice) FROM Votaciones GROUP BY IP)
GROUP BY Votaciones.Producto
HAVING COUNT(Votaciones.Producto)
)
ORDER BY Votos DESC;

Está bien eso?
Al ser tan grande no tarda mas en ejecutarse?
Se ejecuta tal cual o el compilador del mysql la hace más sencilla?
Si se puede, me gustaría depurar un poco más esa consulta, que es gigante.
Porque en realidad hago la misma consulta dos veces.

GRACIAS!

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 09 Jun 2011 09:05 pm
Pues si, es lentísima la consulta.
En access es rápida, pero no en el server con mysql, que mal, ahora que pensé que ya estaba hecho...
Alguien puede depurar eso?

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 13 Jun 2011 07:03 am
Acá te dejo un código PHP, (imgaino que sí podrás manipular de esta forma PHP):
Creo que es entendible el código, traigo todos los prod con votos, luego todos los productos de la bd, y voy comparando si el producto tiene votos, en caso de no tener voto, lo imprimo con votos 0:

Código PHP :

   $link = mysql_connect($server,$user,$pass);
   mysql_select_db($dbname);
    $query = "select count(`votaciones`.`indice`) AS `Votos`,`productos`.`indice` AS `idProducto`, productos.Producto
from (`votaciones` join `productos` on((`votaciones`.`Producto` = `productos`.`indice`)))
where (`votaciones`.`indice` in (
select max(`votaciones`.`indice`) from `votaciones` group by `votaciones`.`ip`)) group by `productos`.`producto`";
   $resultado = mysql_query($query);
   if ($resultado == true)
   { 
      while ($row = mysql_fetch_assoc($resultado))
      { //acá agrego a todos los prod con votos válidos.
         $arrayVotos[] = $row;         
      }
      
      $q = "select * from productos";
      $r = mysql_query($q);
      while ($rw = mysql_fetch_assoc($r)) {
         $arrayProductos[] = $rw; 
         //agregué todos los productos.
      }   
      foreach ($arrayProductos as $rw){                        
         $estaProducto = false;                     
         foreach ($arrayVotos as $row){            
                           
            if ( $rw['indice'] == $row['idProducto'] ) //comparo si está el producto en las votaciones
            {                
//el producto tiene votos, lo imprimo .
               print_r($row); echo "<br>";            
               $estaProducto = true;
      break;                                                      
            }
         }         
                  
         if (!$estaProducto)
         {//para el caso de que el prod esté sin votos.
            $datoAAgregar['Votos'] = 0;
            $datoAAgregar['indice'] = $rw['id'];
            $datoAAgregar['Producto'] = $rw['producto'];            
            print_r($datoAAgregar); echo"<br>";                                                               
         }
                           
      }
      mysql_close($link);
                              
   }
      else{
      echo "error " . mysql_error();
   }


Espero que te sirve, nos vemos :P

P.D: Las vars $server, dbname, $user, $pass, tendrías que poner las que corresponden a tu servidor, base, usuario y pass.

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox
Citar            
MensajeEscrito el 14 Jun 2011 03:19 am
Uff que me lias xD

A ver, yo solo busco una instrucción select, tiene que poderse.

Aún así, gracias,

Por mariahh

7 de clabLevel



 

chrome
Citar            
MensajeEscrito el 14 Jun 2011 03:23 am
Perdoná la curiosidad, pero qué estás desarrollando? No podés modificar la estructura d la tabla, no podés trabajarlo desde php, no podés usar vistas... qué estás haciendo? xD

Por Arteniz

41 de clabLevel



Genero:Masculino  

Programador

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.