Así que tengo una tabla:

CREATE TABLE TABLE_NAME (
    COLUMN_1   char(12)    NOT NULL,
    COLUMN_2   char(2)     NOT NULL,
    COLUMN_3   char(1)     NOT NULL,
    COLUMN_4   int         NOT NULL,
    COLUMN_5   char(2)     NOT NULL,
    COLUMN_6   money       NOT NULL,
    COLUMN_7   smallint    NOT NULL,
    COLUMN_8   varchar(10) NOT NULL,
    COLUMN_9   smallint    NOT NULL,
    COLUMN_10  datetime    NOT NULL
    Primary Key (COLUMN_1, COLUMN_2, COLUMN_3)
)

SELECT COUNT(*) devuelve un valor diferente SELECT DISTINCT COUNT(*). ¿Cómo puede ser esto posible?

También traté de

SELECT COUNT(*) FROM (
    SELECT
        COLUMN_1,
        COLUMN_2,
        COLUMN_3,
        COLUMN_4,
        COLUMN_5,
        COLUMN_6,
        COLUMN_7,
        COLUMN_8,
        COLUMN_9,
        COLUMN_10
     FROM TABLE_NAME
    ) TMP

que devuelve el mismo conde como las distintas consultas.

Estoy un poco cansado, así que espero que no me estoy perdiendo algo obvio, pero no puedo ver cómo con una clave principal y en todos los campos NO NULOS, no puede ser otro recuento total que el recuento de registros únicos.

Por CIERTO, esto es en Sybase ASE 15.

La discrepancia es de un centenar de registros de un millón y medio. También estoy viendo que este problema en varias otras tablas, pero elige sólo uno para el ejemplo.

EDICIÓN:

Debo mencionar en aras de la exhaustividad que he descubierto este problema al escribir un trabajo sencillo completamente copia esta tabla en una base de datos remota. Mi solicitud fue la grabación de un cierto número de operaciones de lectura/escritura, pero no de QA debido a que el número de registros en la base de datos de origen difieren en el número de registros en la base de datos de destino. Ambos valores fueron obtenidos a través de COUNT(*); el número devuelto desde el objetivo (Oracle 10g) era el mismo que el número de operaciones de lectura/escritura grabada por mi aplicación. Como todos los campos en la tabla de origen se define not NULL y una clave principal se define, yo estaba en una pérdida para explicar cómo mi solicitud fue perder a un pequeño número de registros.

Esto es, cuando empecé a usar la alternativa de las consultas mencionadas anteriormente, ambos de los cuales de acuerdo con mis aplicaciones de lectura/escritura de contar, así como el RECUENTO() valor devuelto por el destino. En otras palabras, el único valor que no coincide fue el CONDE() en la base de datos de origen.

Por favor revise mi respuesta.

OriginalEl autor Ickster | 2010-12-02

3 Comentarios

  1. 6

    En la mayoría de las bases de datos que lo soportan, count(*) en realidad no recuperar todos los registros y el número de ellos, sino que recupera algunos de los campos de metadatos que sólo realiza un seguimiento del número de filas (o número aproximado de filas) en la actualidad está almacenado en la tabla. Por otro lado, cuando haces algo que requiere trabajar con datos reales, el dbms se va a recuperar las filas de todos modos, y se contará como era de esperar.

    Por supuesto, es razonable esperar que, independientemente de cómo se implementa, el resultado de count(*) sería el mismo, como más complejo, pero a la consulta equivalente. Que sugeriría, entonces, que (tal vez) de su tabla de metadatos está dañado de alguna manera. (Yo diría que esta es una buena apuesta-no estoy familiarizado con sybase específicamente, pero la mayoría de los dbms tienen una manera de forzar a reconstruir la tabla de métricas… que podría ser vale la pena intentarlo aquí).

    Otra posible explicación es que la base de datos interna de la fila de la tabla de contador no es en realidad diseñado para ser 100% exacto. (esta segunda posibilidad es la pura educados especulación… yo en realidad no sé si esto es cierto de Sybase fila del mostrador o no, pero podría ser digno de mayor investigación).

    buena suerte!

    Gracias. He descubierto que la ejecución de mis consultas en los campos de la tabla obligó a una actualización de los metadatos, por lo que ahora el select count(*) se devuelve el mismo número, como todo lo demás. La posibilidad de algún tipo de rancio caché conde me había ocurrido, pero como nunca me había encontrado con un problema como este, parecía que yo era agarrar a un clavo ardiendo.
    Por favor revise mi respuesta. Tu post es incorrecta.
    Como ya he dicho, yo no sé mucho acerca de Sybase – es muy posible que mi respuesta es incorrecta para ese sistema. Sin embargo, sé que es un hecho, que algunas bases de datos comunes funcionan exactamente de la manera que he descrito. Verificación de la documentación de MySQL count(*) para un ejemplo de.
    Sé que son bien intencionados, compañero. Esta es una de Sybase pregunta (tal vez debería haber dicho «tu post es incorrecta para Sybase»). Sé que MySQL es diferente, he explicado cómo llegan a ser diferentes en la sección de Respuestas en mi respuesta. Sólo por la FAQ, y por encima de todo la identificación de las respuestas incorrectas.

    OriginalEl autor Lee

  2. 1

    Este es un Sybase ASE Respuesta para un Sybase ASE Pregunta

    Se aplica a cualquier Estándar Compatibles con SQL DBMS; no se aplican a los demás.

    La respuesta que usted ha elegido no es el correcto.

    1. COUNT() es un ISO/IEC/ANSI Estándar expresión SQL. Es necesario físicamente contar las filas, lo que significa que será lento en una gran mesa. Es necesario no utilizar la memoria interna residente tablas o catálogo de tablas («metadatos»). Este es un valor de tiempo de ejecución, por lo que si la tabla está activa, se va a seguir cambiando para cada ejecución

      • Lo coloca dentro de los corchetes es muy importante.

      • COUNT(*) devuelve el número de filas como null

      • COUNT(column) devuelve el número de filas donde column No es Null

      • Sí, la colocación de DISTINCTtambién es importante. Esto obliga a que el uso de una mesa de trabajo. Si usted necesita para contar una columna que no es Única, entonces usted no tiene una opción; pero para columnas únicas, no hay necesidad de utilizar DISTINCT

      • DISTINCT se aplica a una columna o una expresión derivada de una columna;

        COUNT (DISTINCT *)

        es de sentido («distinta de todas las columnas»), y ASE 15 tiene un mejorado sustancialmente analizador, que las capturas de tales cosas (versión anterior pareciera dhave devuelve una menos precisa mensaje de error).

      • las filas leído dependerá de su NIVEL de AISLAMIENTO (el número correcto será devuelto para el nivel especificado) y la actividad actual en la base de datos

      • el método más limpio, que evita los extraños resultados que está obteniendo, es el uso de

        COUNT(PK_column)

      • (Ya que este es un CW) Nunca utilice cualquier forma de COUNT() para una comprobación de existencia, como es físicamente los recuentos de las filas. Utilice siempre IF EXISTS con la correcta WHERE cláusula, porque se va a utilizar el índice único.

    2. Si usted necesita una cuenta exacta, pero no quieres leer todas las filas, no hay una función para leer el catálogo de la tabla systabstats, que tiene un recuento de filas en cada tabla. Esto devuelve instantáneamente, sin importar el tamaño de la tabla. La moneda de los valores depende de cómo esté configurado el servidor para el rendimiento, la rubefacción, los puntos de comprobación, etc. systabstats es actualizado de los residentes en memoria de las tablas con dos comandos: ACTUALIZACIÓN de las ESTADÍSTICAS y «a ras de estadísticas». Intente esto:

      EXEC sp_flushstats
      SELECT ROW_COUNT (DB_ID(), OBJECT_ID("table_name") )

    Respuesta a los Comentarios

    Esta Sección No es Relevante para Sybase

    1. Me han proporcionado un limpio explicación volver a su problema, y el sujeto, sin explicar por qué las otras dos respuestas son incorrectas, o por qué su segunda consulta devuelve resultados impredecibles.

    2. Aquí es el Sybase ASE 15.0 Referencia/Bloques de Construcción Manual, COUNT() está en la página 121. Tenga en cuenta que icyrock ha malinterpretado, y ambos han mal interpretado, sin darse cuenta, por supuesto. Su punto de partida fue la confusión, la falta de distinción re * y DISTINCT, de ahí mi intento por llegar a una respuesta clara.

    3. He hecho de esto una Wiki de la Comunidad, por lo tanto mi respuesta es completa re el tema, normalizado, de modo que puede mantenerse como una respuesta completa a cualquier pregunta re COUNT().

    4. En respuesta a los comentarios, para aquellas personas que no han escuchado (sin ofender, pero hay un montón de freeware usuarios de SQL en busca de respuestas aquí en ASÍ). SQL es un Estándar idioma, inventado y desarrollado por IBM en la década de 1980 y aceptado como un Estándar por:

      • la Organización Internacional de normalización,
      • la Comisión Electrotécnica Internacional y (Formato Libro),
      • y copiado por Instituto Americano de Estándares Nacionales (publicación gratuita gracias a la buena vieja de Digital Equipment Corp) un poco más tarde.

      • Ninguno de la open source o freeware «SQL» cumplir con la Estándar. Ellos proporcionan algunos de los componentes (las estructuras de la lengua, las instalaciones, los comandos) de la Norma. Y de aquellos que prestan, que rara vez proporcionan el Estándar Requisito (por ejemplo. manejo de transacciones, seguridad).

      • Por lo tanto lo Sybase y DB2 (rígido volver a Normas), y en menor medida de lo MS («flexible» sobre implementaciones) y Oracle (tramos de las definiciones), debido a que se cumpla el Estándar (sin discutir las pequeñas variaciones), está a años luz de distancia de la MySQLs y la PostGreSQLs del mundo.

      • Entonces hay no Estándar o anti-categoría Estándar.

        MySQL/MyISAM proporciona COUNT() en una manera que es en concreto contra la Norma (esto es claramente evidente en el MySQL Manual de enlace proporcionada por Lee; bueno para no transaccional apps).

        MySQL/InnoDB & BDB proporcionar COUNT() en el que cumpla el Estándar manera.

      • Todos los Estándar de SQL fabricantes ofrecen una gran variedad de Extensiones al Estándar

      • Donde el freeware que tiene valor, es decir, proveen un buen número de Extensiones (en su mayoría en lugar de la Estándar), para facilitar la codificación en los servidores web. Y todos ellos son diferentes.

        .

    5. La NOT NULL en la definición de la tabla no pueden ser inmediatamente de confianza, debido a que la tabla puede haber tenido null columnas en él antes de la definición actual se llevó a cabo. Sin embargo, Sybase, DB2 y contará lanza física, como requisito para el cumplimiento de la Norma. Usted puede probar con una serie de cargos:SELECT COUNT(column_1) from table_name; y, a continuación, compare los condes.

    6. La segunda consulta confundir aún más, sí, porque cuando el interior de la tabla se crea y rellena, el recuento será exacta. Desde que se creó con una expectativa, cumplió con sus expectativas. Pero eso no demuestra nada acerca de que la tabla original.

    Información correcta, pero no relacionadas con la pregunta (ver esquema de la tabla y alternativa de consulta @Ickster publicado)
    Entiendo que la norma se especifica que count() devuelven un conteo físico de las filas, pero sé que la tabla en cuestión era estático y conseguía un resultado de count (), que difieren del número de registros que yo era capaz de leer. Además, el lavado de la estadísticas de hecho, causa count() para devolver el valor correcto. Lo que la norma dice, parece Sybase ASE 15 está haciendo algo diferente.
    ok. Hay un par de razones por las que me votada abajo de su respuesta: – Hay demasiados información irrelevante, es decir, la discusión sobre el RECUENTO del comportamiento para el valor null es irrelevante, ya que el esquema de la tabla ya define todos los campos a ser no nulo. – La parte de ‘systabstats’, es una muy mala idea para escribir proveedor de consultas específicas. Esta consulta podría no ser reemplazable en otro dbms, incluso si es así, no hay garantía de que el comportamiento será el mismo. siguió a continuación……
    – Lee la respuesta ya la se señala la causa más probable de este problema, la alternativa a la consulta (obligando a una mesa de trabajo) muestra que hay una inconexión entre la base de datos y estadísticas reales de la fila numérica. Gritando que ser la respuesta incorrecta sin nada que lo respalde garantiza a algunas de votación para evitar confusiones
    Podría usted por favor, ejecute el paso (5) en mi Respuesta, para cada columna, y presentar los resultados. COUNT() puede ser de confianza, usted necesita entender los sabores.

    OriginalEl autor

  3. 1

    Si no me equivoco, a juzgar por este:

    debe utilizar select count(distinct *). Me gustaría esperar select distinct count(*) siempre devuelve 1, como se dice «dame las filas distintas, cada una de las cuales es un count(*)«, por lo que no siempre va a ser una fila, mientras que select count(distinct *) le da un recuento de filas distintas.

    Por lo que vale, la de arriba que parece ser v12.5 (aunque yo no veo ninguna diferencia), aquí están los 15.0 docs:

    Explícitamente dice lo siguiente:

    count(*) encuentra el número de filas. count(*) no toma ningún argumento, y no puede ser utilizado con distintos. Se cuentan todas las filas, independientemente de la presencia de valores nulos.

    Puede utilizar select count(distinct column_1) o así, pero no select count(distinct *).

    A lo de la versión de los docs se refieren? SELECT COUNT(DISTINCT *). . . dio un error de sintaxis.
    Ver la edición.
    Gracias, realmente fue ASÍ que el sistema de la cotización que «quitado», como * es un carácter especial. He actualizado para el futuro.

    OriginalEl autor icyrock.com

Dejar respuesta

Please enter your comment!
Please enter your name here