Para programadores avanzados en mySQL

Iniciado por flashkeyboard, 3 Mayo 2010, 20:06 PM

0 Miembros y 1 Visitante están viendo este tema.

flashkeyboard


ayuda

la informacion de la tabla para los ejemplos es la siguiente

CREATE TABLE `tabla_test` (
  `idtabla_test` int(10) unsigned NOT NULL auto_increment,
  `nombre` varchar(45) NOT NULL default '',
  `caso` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`idtabla_test`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `tabla_test` VALUES ('1', 'CARLOS', 'A');
INSERT INTO `tabla_test` VALUES ('2', 'CARLOS', 'A');
INSERT INTO `tabla_test` VALUES ('3', 'JUAN', 'C');
INSERT INTO `tabla_test` VALUES ('4', 'JUAN', 'A');
INSERT INTO `tabla_test` VALUES ('5', 'CARLOS', 'C');
INSERT INTO `tabla_test` VALUES ('6', 'CARLOS', 'C');
INSERT INTO `tabla_test` VALUES ('7', 'JUAN', 'C');
INSERT INTO `tabla_test` VALUES ('8', 'CARLOS', 'C');
INSERT INTO `tabla_test` VALUES ('9', 'JUAN', 'A');
INSERT INTO `tabla_test` VALUES ('10', 'JUAN', 'A');
INSERT INTO `tabla_test` VALUES ('11', 'CARLOS', 'C');
INSERT INTO `tabla_test` VALUES ('12', 'JUAN', 'C');
INSERT INTO `tabla_test` VALUES ('13', 'JUAN', 'A');
INSERT INTO `tabla_test` VALUES ('14', 'CARLOS', 'C');


Tengo una tabla de 3 campos de esta forma

ID   NOMBRE   CASO

1   CARLOS   A
2   CARLOS   A
3   JUAN    C
4   JUAN           A
5   CARLOS   C
6   CARLOS   C
7   JUAN    C
8   CARLOS   C
9   JUAN    A
10   JUAN    A
11   CARLOS   C
12   JUAN    C
13   JUAN    A
14   CARLOS   C


QUE QUERY DEBO USAR PARA QUE ME DEVUELVA ESTE RESULSET


NOMBRE      CASOS_ABIERTOS      CASOS_CERRADOS

JUAN            4                        3

CARLOS         2                         5




EH INTENTADO DE TODO, PERO ES NOTABLE QUE MI NIVEL EN MYSQL NO ES MUY ALTO

UTILICE SUBQUERYS, COUNTS Y NADA


LO QUE TENGO ES LO SIGUIENTE

PERO ME DA ERROR

SELECT
nombre,
count(caso) as Abiertos,
(SELECT
count(caso)
FROM tabla_test t
where caso = 'C'
GROUP BY nombre) as Cerrados
FROM tabla_test t
where caso = 'A'
GROUP BY nombre


GRACIAS!  :-[

^Tifa^

Ando con el tiempo encima lo siento.....

No podre expandirme pero....

En 1 sola consulta tu estructura (nisiquiera con un Self Join) lo veo factible... los motivos te los explico luego que ando rapidito...

Pero, hay formas de sacar lo que quieres, ya sea con un CURSORS de MySQL, ya sea con un UNION o ya sea creando otra Tabla en el motor MEMORY para que se resetee la data ya que esta en memoria volatil... y usar algo tipo:

Tabla:

Citarmysql> create table Temporal(
    -> nombres char(20),     
    -> abiertos int,         
    -> cerrados int) engine = memory;

Y para llenarla:

Citarmysql> insert into Temporal values((select nombre  from test where caso = 'A' group by(nombre) limit 1), (select count(caso) from test where caso = 'A' group by(nombre) limit 1), (select count(caso) from test where caso = 'C' group by(nombre) limit 1));

Tengo que usar LIMIT 1 porke si quieres insertar mas tendras que sacar la data primero en un bucle y ir insertandola ya que es la unica forma...

Luego te explico... que ando volando.

alone-in-the-chat

O.O

Tiempo sin postear por aqui de aburrido cogi tu post lo mire y como dice Tifa tienes esas maneras de hacer la cosa .

Pero cuando me entra curiosidad me pongo a trastear y vi que si la pude sacar.

Pueba con esto

Código (sql) [Seleccionar]


SELECT t.nombre , COUNT(*) as Abierto , (SELECT COUNT(*) FROM tabla_test WHERE caso = 'C' AND nombre=t.nombre ) as Cerrados
FROM tabla_test t WHERE caso='A'
GROUP BY nombre



Espero te sirva.


Saludos!!
Because maybe
You're gonna be the one that saves me
And after all
You're my wonderwall
d[n_n]b

^Tifa^

Gracias alone-in-the-chat... ultimamente me ando quedando cortita de tiempo (a excepcion de los fines de semana). Y pues es dificil para mi, concentrarme en responder preguntas de esta indole cuando tengo el tiempo encima, y cosas pendientes por terminar en ese reducido tiempo  :xD  pero grax si el usuario vuelve a lo mejor le pueda servir.

Una cosa si debes llevar claro, tanto tu como el... cuidado con los COUNT all y los valores NULL

Besis  :-*

doreymis

hola que tal.. tengo un problemita similar al de flashkeyboard..
se trata de que necesito que me devuelva el listado de la nomina junto con los dias laborados y los dias sancionados.

les dejo mi sentencia

select empleado.ci, empleado.nombre1, empleado.nombre2, empleado.apellido1,empleado.apellido2,
empleado.cargo, asistencia.quincena , count(asistencia.asistencia) as "dias laborados",

(select count(asistencia.sancion) as "sancion" from asistencia join empleado
where asistencia.ci = empleado.ci
and asistencia.sancion = true
and asistencia.quincena = "2da de Mayo" group by asistencia.ci) as "dias sancionados"

from empleado join asistencia
where asistencia.asistencia=true
and  asistencia.ci=empleado.ci
and asistencia.quincena="2da de Mayo" group by asistencia.ci



y este es el error que me genera:
Subquery returns more than 1 row.


...:::little lulu:::...

^Tifa^

Cuidado, cuidado, cuidado con los GROUP BY en una Subquery que no guarde el resultado en un arreglo  ;)

Código (sql) [Seleccionar]

(select count(asistencia.sancion) as "sancion" from asistencia join empleado
where asistencia.ci = empleado.ci
and asistencia.sancion = true
and asistencia.quincena = "2da de Mayo"[b] group by[/b] asistencia.ci) as "dias sancionados"



En esa consulta se retornara mas de 1 registro, sin embargo como consulta independiente sola si funcionaria, pero como subconsulta NO al no ser claro esta que guardaras los registros retornados en un arreglo... algo mas o menos asi:

Código (sql) [Seleccionar]

select empleado.ci, empleado.nombre1, empleado.nombre2, empleado.apellido1,empleado.apellido2,
empleado.cargo, asistencia.quincena , count(asistencia.asistencia) as "dias laborados" , campo IN

(select count(asistencia.sancion) as "sancion" from asistencia join empleado
where asistencia.ci = empleado.ci
and asistencia.sancion = true
and asistencia.quincena = "2da de Mayo" group by asistencia.ci) as "dias sancionados"

from empleado join asistencia
where asistencia.asistencia=true
and  asistencia.ci=empleado.ci
and asistencia.quincena="2da de Mayo" group by asistencia.ci



Pero lo anterior puede que no precisamente te retorne lo que andas solicitando en realidad, (deberia evaluar la estructura de las tablas existentes, los registros, y analizar y ejecutar tu consulta SQL que no lo he hecho  :xD )

Pero no puedes usar la clausula GROUP BY en una subquery donde no exista una especie de arreglo que capte dicho resultados, en tu caso como No existe un arreglo que capte y asumiendo que si usas IN no retorne lo que solicitas, pues tendras que obviar el GROUP BY de la subquery y unicamente usar campos con igualaciones constantes (digase  WHERE CAMPO = CAMPO AND CAMPO = CAMPO) y si tu tabla respeta la normalizacion, con campo = campo no debera retornar mas de 1 registro duplicado (que si retorna mas de un duplicado te pasara el mismo inconveniente) y tendras que filtrar la subquery usando algo como LIMIT por ejemplo o la clausula DISTINCT

Salu2

doreymis

hola... sabes que de leer y leer buscar y buscar pude llegar a una solucion...
me hacia falta algo que filtrara la sentencia...

lo coloque de esta manera y me trajo exactamente los resultados que necesitaba:

select empleado.ci, empleado.nombre1, empleado.nombre2, empleado.apellido1,empleado.apellido2,
empleado.cargo, asistencia.quincena ,
count(asistencia.sancion)as "sancionados",
(select count(asistencia.asistencia)
from asistencia join empleado
where asistencia.ci = empleado.ci
and asistencia.asistencia = true
and asistencia.quincena = "2da de Mayo"
group by asistencia.ci having asistencia.ci = empleado.ci) as "laborados"
from asistencia join empleado
where asistencia.ci = empleado.ci
and asistencia.sancion = true
and asistencia.quincena = "2da de Mayo" group by asistencia.ci

les dejo mi solucion para quien pueda necesitarla....  ;-) ;-) ;-)

gracias..!!!  ;D
...:::little lulu:::...

nicknamex

Primeramente Muchas gracias por las anteriores entradas pues me sirvieron mucho mucho ;-).

Ahora quisiera saber si alguien sabe como formatear la salida de un SELECT para que quede así:
Registro1,Registro2,Registro3,Registro4
(... en un solo texto)
Actualmente lo hago con el PHP, pero creo que sería mejor hacerlo directamente con MySQL
Gracias de Antemano

Shell Root

No entendí así?
Código (sql) [Seleccionar]
mysql> SELECT -1 As Num1, -2 As Num2, -3 As Num3, -4 As Num4, -5 As Num5;

+------+------+------+------+------+
| Num1 | Num2 | Num3 | Num4 | Num5 |
+------+------+------+------+------+
|   -1 |   -2 |   -3 |   -4 |   -5 |
+------+------+------+------+------+

1 row in set (0.00 sec)


Entonces que dentro de un text, aparezca así:
Código (bash) [Seleccionar]
sText = " -1, -2, -3, -4, -5 "

Es mejor hacerlo directamente desde PHP. Creo que es más fácil.
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

nicknamex

Por ejemplo si tengo un típico: SELECT Registro FROM Tabla WHERE id>30 y esas salidas quererlas colocar en una casilla de una consulta mayor
SELECT id, nombre, apellido, FuncionX(SELECT Registro FROM Tabla WHERE id>30)Por ejemplo quisiera un salida así

idnombreapellidoRegistros
1 fulano detal registro1,registro2,registro5
2mengano pelli registro2,registro7
. Creo que lo que quiero es algo parecido a una consulta de referencias cruzadas, con tablas externas.
Gracias