Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   ¿como saber cuantos registros devuelve un select? (https://www.clubdelphi.com/foros/showthread.php?t=87100)

JXJ 14-11-2014 05:40:21

¿como saber cuantos registros devuelve un select?
 
hola.

comop puedo hacer pasa conocer cuantos registros obtengo en un select en un stored procedure

en delphi hago una consulta
Código Delphi [-]
select * from tabla where alumno = 'jxj'
//y con un 
for i := o to query1.recordcount - 1 do 
begin
// aqui hago algo
end;


// o solo con el recordCount  obtengo la cantidad de registros

¿en firebird como se puede hacer lo mismo?
¿un bucle por los registros devuelto y obtener la cantidad de registros?


gracias

Ñuño Martínez 14-11-2014 09:00:35

Si preguntas cómo obtenerlo vía SQL, es fácil:

Código SQL [-]
SELECT COUNT (*) AS num_registros FROM tabla WHERE blablabla;

Neftali [Germán.Estévez] 14-11-2014 10:00:54

Imagino que los motores hacen esto mismo cuando ejecutas la SQL que te ha puesto Ñuño, pero yo por costumbre suelo hacer una cosa asi:

Código SQL [-]
SELECT COUNT (campo_clave_primaria) FROM TABLA WHERE 'blablabla'

duilioisola 14-11-2014 12:19:09

Creo que preguntas como hacer lo que ejemplificas dentro de un Stored Procedure en Firebird.

Código SQL [-]
for select campo1, campo2, ... from alumnos
    where alumno = 'jxj'
    into :var1, :var2
begin
    /* hago algo */
end

Si fuera en Delphi, en casos como el que presentas y no averiguo cuantos hay. Recorro hasta llegar al final con un WHILE
Código Delphi [-]
while not Query1.EOF do
begin
   // Hago algo
   Next;
end;

duilioisola 14-11-2014 12:33:50

Código SQL [-]
/* Ejemplo para sacar un promedio de notas de un alumno */
create procedure promedio (
    alumno varchar(10))
returns (
    promedio double precision)
as
declare variable cantidad integer;
declare variable total_nota double precision;
begin
    /* Averiguo cuantas notas hay */
    select count(*)
    from notas_alumnos
    where
    alumno = :alumno
    into :cantidad;

    /* Sumo las notas */
    totalnota = 0;
    for select nota
        from notas_alumnos
        where
        alumno = 'jxj'
        into :nota
    do
    begin
        totalnota = totalnota + nota;
    end

    /* Calculo el promedio */
    promedio = totalnota / cantidad;

    suspend;
end

Casimiro Notevi 14-11-2014 12:55:35

Cita:

Empezado por duilioisola (Mensaje 484757)
Si fuera en Delphi, en casos como el que presentas y no averiguo cuantos hay. Recorro hasta llegar al final con un WHILE
Código Delphi [-]
while not Query1.EOF do 
begin    
  // Hago algo    
  Next; 
end;

No recuerdo ahora, de memoria, pero para hacer eso será mejor algo así:
Código Delphi [-]
Query1.Last
Query1.RecordCount

roman 14-11-2014 17:53:40

Cita:

Empezado por Casimiro Notevi (Mensaje 484762)
No recuerdo ahora, de memoria, pero para hacer eso será mejor algo así:
Código Delphi [-]
Query1.Last
Query1.RecordCount

Ya, pero eso es poco práctico. Mejor el count(*).

// Saludos

Casimiro Notevi 14-11-2014 17:59:20

Sí, pero es que dice "desde delphi" y hace un bucle desde inicio hasta el final.

Desde delphi también puede hacer el count, desde luego.

JXJ 14-11-2014 19:42:19

A eso me refirero todo en Stored procedure de firebird yo le llamo PL/SQL pero me han dicho que en firebird no se llama asi. solo en oracle.

duilioisola

no sabia que con un bucle for se podia recorrer los resultados de una consulta.

Si Roman, con un count(*) obtengo la cantidad de registros, lo acabo de probar.


gracias

fjcg02 14-11-2014 21:17:45

hola,
es más eficiente hacer count(1) que count(*) a efectos de trabajo del motor de bbdd.

Saludos

ecfisa 14-11-2014 22:07:47

Cita:

Empezado por fjcg02 (Mensaje 484802)
hola,
es más eficiente hacer count(1) que count(*) a efectos de trabajo del motor de bbdd.
...

:eek: ¡ Esa no la tenía registrada !

( Gracias por desasnarme ;) )

Saludos :)

Casimiro Notevi 14-11-2014 22:24:05

Siempre uso un campo clave, ejemplo: count(id)
Pero nunca había visto count(1) ¿qué hace exactamente?

ecfisa 14-11-2014 22:36:27

Cita:

Empezado por Casimiro Notevi (Mensaje 484812)
Siempre uso un campo clave, ejemplo: count(id)
Pero nunca había visto count(1) ¿qué hace exactamente?

Si, sería bueno saberlo... Mirando las estadísticas hay una marcada diferencia (sobre 17698 pacientes):
Código SQL [-]
SELECT COUNT(*) FROM PACIENTES
Código:

32934 fetches, 0 marks, 692 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 48 index, 15698 seq.
Delta memory: 21436 bytes.
Total execution time: 0.156s


Código SQL [-]
SELECT COUNT(1) FROM PACIENTES
Código:

32760 fetches, 0 marks, 0 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 0 index, 15698 seq.
Delta memory: 96 bytes.
Total execution time: 0.031s

Saludos :)

Edito: Obtuve el mismo resultado usando COUNT(0) (0.031s) y una diferencia menor a COUNT(*), usando COUNT(ID) (0.047s) .

mamcx 14-11-2014 23:21:27

Explicado y con pros y contras:

http://stackoverflow.com/questions/2...hich-is-better

RONPABLO 15-11-2014 08:36:09

Cita:

Empezado por Casimiro Notevi (Mensaje 484812)
Siempre uso un campo clave, ejemplo: count(id)
Pero nunca había visto count(1) ¿qué hace exactamente?

pues en un query uno puede hacer algo como:
Código SQL [-]
Select 1 as numero_Constante, id, nombre, 'Casi' as NombreConstante from MiTabla where fecha between :f1 and :f2

Pues así como puedo poner como constante un numero, también puedo contar cuantas veces sale dicha constante o sumarla con un Sum(1)

RONPABLO 15-11-2014 08:50:10

Código SQL [-]
create procedure SpAlgo (alumno varchar(10)) returns (cantidad integer, RegistroActual integer,id Integer, Nombre varchar(100)) as 
begin     
   select count(1) from notas_alumnos where alumno = :alumno into :cantidad;
   RegistroActual = 0;
   for select nombre, id from notas_alumnos where alumno = :alumno   into :nombre, :id  do
   begin
      registroActual = registroActual + 1;
      suspend;
   end  
end

COn este procedimiento puedo en cualquier momento saber cuantos registros tengo o decir en que registro voy de todos los que tengo

Casimiro Notevi 15-11-2014 10:09:34

Entiendo, aunque no le encuentro utilidad :D

RONPABLO 15-11-2014 19:11:23

Cita:

Empezado por Casimiro Notevi (Mensaje 484849)
Entiendo, aunque no le encuentro utilidad :D

no le encuentras utilidad a count(1) ?, pues la utilidad es que consume menos recursos comparado a un count(*), y el count(UnCampo) existe la posibilidad de que el campo sea null (aunque en la clave primaria no) y no sea contado

Casimiro Notevi 15-11-2014 23:27:42

Por eso digo, es que yo siempre uso count(campoclave)

fjcg02 16-11-2014 13:46:13

Hola,
respecto a lo de count(1), yo no lo sabía hasta que hace un año un "gurú" me dijo que lo hiciera así. Es una persona con conocimientos de Oracle de muchísimo nivel. Cuando pueda le preguntaré porqué es más eficiente.

Bajo mi punto de vista, y dado que cuando haces un count de un campo el motor debe evaluar si es nulo o no, ahí puede haber una pérdida de tiempo. Sin embargo, si pones count(1), solamente revisará si hay registro o no, independientemente del valor que tengan los campos. Aunque esto indudablemente dependerá de cada motor de bbdd , de cómo parsee las sentencias sql y qué ejecute realmente tras el parseo. Ya sabeis que los motores en ocasiones hacen una transformación de las sentencias sql para optimizar los resultados ( aunque en ocasiones consigan lo contrario).

Un saludo


La franja horaria es GMT +2. Ahora son las 09:39:53.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi