Registros repetidos tabla SQL


Hay ocasiones en las que necesitamos saber si algún registro esta repetido en una tabla, ya sea por el id o por el nombre o por cualquier otro campo que queramos saber, incluso puede ser más de un campo. En esos casos se debe emplear una consulta sencilla de SQL para que nos indique cuales registros aparecen más de una vez en la tabla de acuerdo a los campos que estemos comparando.
Entonces para explicarlo voy poner el siguiente ejemplo: supongamos que tenemos la tabla Cliente y que queremos saber que registros de clientes por nombre y apellido están repetidos. Entonces para dicho ejemplo realizamos la siguiente consulta:
Select Nombre, Apellido, Count(*) As CantidadRepetidos
From Cliente
Group By Nombre, Apellido
Having Count(*) > 1
Order By Nombre, Apellido
En esta consulta lo que se hace es seleccionar los campos por los cuales vamos a comparar si hay registros repetidos, en este caso, Nombre y Apellido. También en el select colocamos la función de conteo de registros Count para que nos obtenga el número de registros por esos campos, pero para que funcione la consulta debemos realizar una agrupación por esos mismos campos que pusimos en el select, es decir, Nombre y Apellido. Por último adicionamos la cláusula Having para que evalue la funcion Count y nos devuelva solo los registros en los que esa funcion nos devuelva valores mayores a uno, es decir, donde el Apellido y Nombre estén más de una vez en la tabla, o sea los registros repetidos.
Espero les haya quedado claro y les aporte mucho en su conocimiento sobre SQL. No olviden que pueden comentar cualquier inquietud al respecto.

71 comentarios sobre “Registros repetidos tabla SQL

  1. Hola, está super bien explicado, y adicional te quiero pregutar cómo puedo hacer para contar esos datos solo una vez, es decir que si el campo nombre y apellido es igual en varios registros, solo me lo tenga en cuenta una vez, tengo que 3 campos que pueden ser igual a su vez pero solo me debe contar como un dato.

    Mil gracias!

    Me gusta

    1. Hola Fernanda,

      Según entiendo quieres obtener los registros de una tabla donde aquellos registros que estén repetidos se listen una sola vez. Si lo que entiendo es correcto, entonces puedo sugerirte la siguiente consulta:

      Select Nombre, Apellido, Genero
      From Cliente
      Group By Nombre, Apellido, Genero
      Having Count(*) > 1
      UNION ALL
      Select Nombre, Apellido, Genero
      From Cliente
      Group By Nombre, Apellido, Genero
      Having Count(*) = 1
      Order By Nombre, Apellido, Genero

      En esta consulta se hace la agrupación para obtener los registros repetidos más de una vez por «Nombre», «Apellido» y «Género» y se une con otra consulta similar pero que obtiene solamente los registros únicos o que aparecen sola una vez (Having Count(*) = 1) por «Nombre», «Apellido» y «Género».

      Si lo que entiendo de tu inquietud no es correcto, me la podrías aclarar de otra manera, la idea es que en lo posible pueda colaborarte.

      Me gusta

      1. Hola Jhuvier, depronto no me expliqué muy bien, te cuento:

        Tengo una tabla llamada articulos (son artículos científicos), entonces resulta que un mismo artículo puede tener varios autores, y cada autor registra su artículo de forma individual porque debe quedar en su hoja de vida, entonces a mi se me ocurrió que la forma de evitar contar más de una vez el mismo artículo es identificando cúales tienen los mismo datos, por ejemplo: el número de volúmen, número de fasículo, página inicial e isnn, si hay dos registros con estos mismo datos es porque se refiere al mismo artículo, encontré este código, no se si es correcto

        select count(distinct a_volumen, a_fasiculo, a_paginicial, isnn )

        from articulos

        Hasta el momento me funciona porque si tengo por ejemplo 6 registros y dos son repetidos, me está devolviendo que hay 5 registros.

        Por favor me dices si estoy en un error o si hay otra forma de realizarlo.

        Mil gracias por tu ayuda!

        Me gusta

      2. Entiendo ahora, gracias por tu aclaración. Tu consulta está bien, realiza una distinción de los registros por esos campos, lo cual hace que no salgan duplicados y con el «count» obtienes la cantidad finalmente. Así que es correcta esa solución y aunque hay otras formas de hacerlo, la que tu tienes es la más sencilla.

        Me gusta

      3. Jhuvier, que pena contigo pero tengo otro problema que no he sido capaz de resolver, siguiendo con el tema de la tabla artículos, con lo anterior logro saber cuantos artículos se han publicado sin repetir ninguno, pero entonces ahora necesito una consulta que me devuelva la lista de artículos pero sin repetirme resultados, en el código que tu me enviaste el efectivamente me arroja los no repetidos, pero por ejemplo si yo quiero listar el nombre de los artículos, pero con la condición de que no esté repetido los campos: a_volumen, a_fasiculo, a_paginicial, isnn no se cómo lograrlo, yo hice el siguiente código de acuerdo a tu orientación

        Select a_volumen, a_fasiculo, a_paginicial
        From articulos
        Group By a_volumen, a_fasiculo, a_paginicial
        Having Count(*) > 1
        UNION ALL
        Select a_volumen, a_fasiculo, a_paginicial
        From articulos
        Group By a_volumen, a_fasiculo, a_paginicial
        Having Count(*) = 1
        Order By a_volumen, a_fasiculo, a_paginicial

        Entonce este código me devuelve 5 registros de 7 porque 2 son repetidos, pero ¿cómo hago para que adicional a esas tres columnas me muestre el la columna nombre del artículo? porque si la pongo en el primer select, entonces me arroja 7 registros porque ya no tomaría los 4 campos como requeridos

        Me gusta

    1. Hola Fernanda,

      Bueno no te preocupes, te cuento. Al incluir un campo más en la consulta, la agrupación hará una distinción por ese campo adicional, entonces en el caso de agregar el nombre del artículo, SQL revisará si el nombre es igual o diferente en los registros repetidos, por lo que si es igual seguirá obteniendo los mismos resultados, pero si los nombres son diferentes entonces empezarán a salir más registros. Me explico, supongamos que tenemos los siguientes registros:

      DatosMuestraRegistrosRepetidos

      Al incluir el campo nombre en la consulta, de la siguiente forma:

      Select a_volumen, a_fasiculo, a_paginicial, a_nombre
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial, a_nombre
      Having Count(*) > 1
      UNION ALL
      Select a_volumen, a_fasiculo, a_paginicial, a_nombre
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial, a_nombre
      Having Count(*) = 1
      Order By a_volumen, a_fasiculo, a_paginicial, a_nombre

      La agrupación tendrá en cuenta el campo «a_nombre», por lo que los artículos «La guerra nunca acaba» y «Siendo jovenes» se muestran en el resultado a pesar de que los primeros 3 campos de estos dos artículos son totalmente iguales. Esto es debido a que hay dos nombres que son diferentes. A diferencia de este caso, el artículo «Niños en conflicto armado», si tiene todos los 4 campos iguales incluyendo el nombre, por lo que entonces la agrupación los unifica en un solo registro como se puede ver a continuación:

      ResultadoDatosMuestraRegistrosRepetidos

      Para tu caso particular, debes preguntarte si quieres obtener los nombres de todos los artículos incluso los repetidos o si quieres obtener solo un nombre por cada registro repetido ya sea que tenga diferentes nombres o no. Si escoges la primera opción entonces la consulta anterior te sirve, pero si escoges la segunda opción entonces debes quitar el campo «a_nombre» del «Group By» y en el «Select» pones el campo «a_nombre» dentro de una función de agregado ya sea «Min» o «Max», de esta manera por cada registro repetido obtendrás un solo registro con el mínimo o máximo nombre sea cual sea. Ten en cuenta que el máximo o el mínimo nombre se obtiene de acuerdo al orden alfabético. La consulta quedaría así:

      Select a_volumen, a_fasiculo, a_paginicial, Min(a_nombre) AS a_nombre
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial
      Having Count(*) > 1
      UNION ALL
      Select a_volumen, a_fasiculo, a_paginicial, Min(a_nombre) AS a_nombre
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial
      Having Count(*) = 1
      Order By a_volumen, a_fasiculo, a_paginicial, a_nombre

      El resultado sería el siguiente:

      ResultadoDatosMuestraUnNombrePorRegistroRepetido

      Como puedes ver, entre «La guerra nunca acaba» y «Siendo jovenes» que tienen los tres primeros campos totalmente iguales, se muestra «La guerra nunca acaba» que es el mínimo nombre de los dos de acuerdo al orden alfabético. El otro registro repetido que es «Niños en conflicto armado» sigue saliendo una sola vez ya que los repetidos tienen el mismo nombre.

      Me gusta

      1. Ay Jhuvier, te quedo totalmente agradecida!!! la segunda opción era exactamente lo que necesitaba, porque en «teoría» si tienen el mismo número de volumen, fasículo y página inicial, deben tener el mismo nombre, sin embargo pasa que al ser ingresados por diferentes personas el título puede cambiar en una letra entonces no lo reconocería como igual.

        De nuevo mil y mil gracias y disculpa tanta molestia

        Feliz día!

        Me gusta

  2. Hola necesito ayuda en una consulta sql, tengo una tabla de clientes donde se repiten DNI y nombre en algún registro. La tabla tiene 17 columnas y al hacer un select * lógicamente salen los campos repetidos, pero necesito hacer un select de todos los campos/columnas sin que muestre los registros repetidos que tengan igual el DNI y el nombre. Utilizo la consulta que dices del having count(*) >1 y having count(*)=1 pero claro con los campos DNI y nombre perfecto, pero como pido todos los campos select * utilizando este método con tantas columnas?

    Me gusta

    1. Hola Josu, puedes basarte en la siguiente consulta, donde aparte de los campos agregados en el Group BY se adiciona a_nombre para que quede en el resultado final sin que afecte los repetidos:

      Select Repetidos.a_volumen, Repetidos.a_fasiculo, Repetidos.a_paginicial, articulos.a_nombre
      From ( Select a_volumen, a_fasiculo, a_paginicial
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial
      Having Count(*) > 1) As Repetidos Inner Join articulos
      On articulos.a_volumen = Repetidos.a_volumen And articulos.a_fasiculo = Repetidos.a_fasiculo And articulos.a_paginicial = Repetidos.a_paginicial

      Saludos.

      Me gusta

  3. hola buen dia estoy trabajando en un sistema pero me sale que no puedo agregar por que el id ya existe error primary key pedido no se puede insertar una clave dublicada dbo.pedido, como puedo hacer para eliminar ese error si borro el duplicado no presentara problema

    Me gusta

    1. Hola Jose, debes poner una validación para verificar que no exista ese id, algo cómo:

      IF EXISTS(SELECT 1 FROM dbo.pedido WHERE columnaLlavePrimaria = 12)

      Dónde 12 es el id que quieres insertar. Si ingresa al IF es porque ya hay un registro con ese id. Espero te sirva de ayuda.

      Me gusta

  4. hola tengo un caso parecido al de Fernanda, solo que yo tengo dos campos con valores diferentes, es decir, en vez de solo el a_nombre, también tengo «fecha», entonces quiero consultar el registro que tenga las fecha mas antigua, pero me que arroje también el nombre, no importa cual sea. Cuando hago la consulta y le pongo MIN(FECHA) me sigue arrojando los 3 registros repetidos, dado que en el campo nombre son distintos. Si quito del BY GROUP el campo NOMBRE me manda error de que no es un campo de la funcion de AGREGADO. Mi campo en realidad no es NOMBRE sino OBSERVACIONES y es de tipo MEMO ojala me pueda ayudar. Gracias

    Me gusta

    1. Hola Oscar, suponiendo que ese campo fecha se llama a_fecha, la consulta que puedes hacer es la siguiente:

      Select Repetidos.a_volumen, Repetidos.a_fasiculo, Repetidos.a_paginicial, articulos.a_nombre, articulos.a_date
      From ( Select a_volumen, a_fasiculo, a_paginicial, Min(a_date) As a_date
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial
      Having Count(*) > 1) As Repetidos Inner Join articulos
      On articulos.a_volumen = Repetidos.a_volumen And articulos.a_fasiculo = Repetidos.a_fasiculo And articulos.a_paginicial = Repetidos.a_paginicial And articulos.a_date = Repetidos.a_date

      Espero te sirva de ayuda.

      Me gusta

  5. Estimados muy buenos sus aportes.

    Por favor su ayuda tengo esta tabla

    CIU CLAVE
    15 12345
    2 12345
    35 12345
    8 11111
    8 11111
    5 22222
    13 33333
    10 33333

    Necesito desplegar unicamente claves duplicadas (Mas de un registro) pero que estén asignadas a CIU diferentes.

    Es decir la consulta debería desplegar solo estos registros
    CLAVE No de CIU’s
    12345 3
    33333 2

    Por favor su ayuda.

    Me gusta

    1. Hola Danny, la consulta sería la siguiente:

      Select CLAVE, Count(*) NumeroRepetidos
      From (Select CIU, CLAVE, Row_Number() Over(Partition By CIU, CLAVE Order By CIU, Clave) As Orden
      From Claves) As Base
      Where Orden = 1
      Group By CLAVE
      Having Count(*) > 1

      En esta consulta utilizamos la función Row_Number() para que nos indique que claves hacen parte de un mismo CIU, una vez con esa información se hace el mismo group by que utilice en el post original y de esa manera nos salen las claves repetidas que están asignadas a diferentes CIU.

      Espero te sirva de ayuda. Saludos.

      Me gusta

    1. Jhuvier, Cordial Saludo,

      El Caso es el siguiente:

      Tengo una Tabla Cartera con los campos (Pagare, NroCuota, Cuota, FechaPactada, AbonoInteres, AbonoCapital, SaldoI, SaldoK, Cedulasociado, AñoMesPago, AbonoI, AbonoK, IntCorriente, IntMora, Deterioro, Plazo, PlazoD, TasaColocacion, TasaColocacionD, TasaEA, TRef, TRefD, Provision, ValorTotalCostas, VP, VF, VP_TREF), de los cuales en ciertos Pagare hay dos NroCuota(0) uno por la FechaPactada en el plan de pago y la otra con una FechaPactada un mes anterior a la del plan de pago, esto se debe a que pago antes de la fechaPactada en el plan de pago, como hago para combinar o unir estas dos filas en una sola en la cual para que dichos Pagare queden con una sola NroCuota(0) en la cual los siguientes campos deben traer de la NroCuota(0) del Plan de Pago: Pagare, NroCuota, Cuota, FechaPactada, AbonoInteres, AbonoCapital, SaldoI, SaldoK, IntCorriente, IntMora, Deterioro, Plazo, PlazoD, TasaColocacion, TasaColocacionD, TasaEA, TRef, TRefD, Provision, ValorTotalCostas, VP, VF, VP_TREF) y los siguientes se deben traer de la NroCuota(0) de los pagos del crédito.

      Quedo atenta a sus comentarios.

      Agradezco la atención prestada y en espera de su pronta y positiva respuesta, me despido deseándole éxitos en sus labores.

      Me gusta

      1. Hola Jona, buen día.

        Para entender un poco más el escenario que me planteas quisiera que por favor me proporcionaras un ejemplo con datos, donde puedas mostrar el resultado esperado. En este momento por ejemplo, no sé de qué manera se identifica una cuota del plan de pago de la otra cuota, no sé cómon quedan las fechas de cada una, qué información cambia entre las cuotas de un mismo pagaré y qué información es igual. La idea es tener clara la situación para poder colaborarte. Quedo atento a tu respuesta. Gracias.

        Me gusta

    1. Hola Fabián, la consulta te va a listar los registros que tengan el mismo valor en un determinado campo, en este caso, si por ejemplo hubiera dos registros con la misma dirección en el campo correo: hola@hola.com (primer registro) y hola@hola.com (segundo registro), entonces te traería estos dos registros porque están repetidos, el valor es exactamente el mismo. De todas maneras si tu caso es más complejo, puedes propocionarme un ejemplo más detallado de lo que necesitas.

      Me gusta

  6. @Jhuvier en referencia a tu comentario del 12 julio, 2013 a las 10:38 am:
    «Al incluir el campo nombre en la consulta, de la siguiente forma:

    Select a_volumen, a_fasiculo, a_paginicial, a_nombre
    From articulos
    Group By a_volumen, a_fasiculo, a_paginicial, a_nombre
    Having Count(*) > 1
    UNION ALL
    Select a_volumen, a_fasiculo, a_paginicial, a_nombre
    From articulos
    Group By a_volumen, a_fasiculo, a_paginicial, a_nombre
    Having Count(*) = 1
    Order By a_volumen, a_fasiculo, a_paginicial, a_nombre

    La agrupación tendrá en cuenta el campo “a_nombre”, por lo que los artículos “La guerra nunca acaba” y “Siendo jovenes” se muestran en el resultado a pesar de que los primeros 3 campos de estos dos artículos son totalmente iguales.»

    Cómo sería la consulta para solamente obtener los registros con los artículos “La guerra nunca acaba” y “Siendo jovenes” únicamente?

    En espera de tu pronta respuesta
    Muchas gracias

    Me gusta

    1. Hola Randy, la consulta sería de la siguiente manera:

      Select Repetidos.a_volumen, Repetidos.a_fasiculo, Repetidos.a_paginicial, articulos.a_nombre
      From ( Select a_volumen, a_fasiculo, a_paginicial
      From articulos
      Group By a_volumen, a_fasiculo, a_paginicial
      Having Count(*) > 1) As Repetidos Inner Join articulos
      On articulos.a_volumen = Repetidos.a_volumen And articulos.a_fasiculo = Repetidos.a_fasiculo And articulos.a_paginicial = Repetidos.a_paginicial

      Saludos.

      Me gusta

      1. Hola Antonio,

        Es creada a partir de una subconsulta en el momento que se ejecute el query. En este caso a la subconsulta se le da el nombre «Repetidos» pero puede ser cualquier otro nombre.

        Me gusta

  7. Muchas gracias Jhuvier, una última duda:
    Cómo sería una consulta para 3 campos, en donde quiero identificar si el tercero se repite en base al segundo, explico un poco:
    Supongamos que tengo una tabla y que tiene los campos numero_ticket, articulo y precio, quiero identificar si existe un articulo 2 veces dentro del mismo numero de ticket con diferente precio es decir el resultado de la consulta debería ser asi:

    numero_ticket || articulo || precio
    ———————————————————–
    A112 || lampara || 240
    A112 || lampara || 390
    G874 || cafetera || 877
    G874 || cafetera || 401

    El propósito sería identificar todos los articulos repetidos cuando se encuentren dentro del mismo ticket pero con precios diferentes.

    Disculpa las molestias, estoy muy agradecido por tu ayuda
    En espera de tu pronta respuesta
    Muchas gracias

    Me gusta

    1. Hola Randy, suponiendo que tu tabla se llama «Productos», la consulta sería la siguiente:

      WITH ProductosRepetidos AS(
      SELECT numero_ticket, articulo
      FROM (SELECT numero_ticket, articulo, precio, ROW_NUMBER() OVER(PARTITION BY numero_ticket, articulo, precio ORDER BY numero_ticket, articulo, precio) AS marcador
      FROM Productos) AS RegistrosMarcados
      GROUP BY numero_ticket, articulo, marcador
      HAVING COUNT(*) > 1
      )

      SELECT Productos.numero_ticket, Productos.articulo, Productos.precio
      FROM ProductosRepetidos INNER JOIN Productos ON Productos.numero_ticket = ProductosRepetidos.numero_ticket AND Productos.articulo = ProductosRepetidos.articulo

      La CTE fue usada para mostrar finalmente los articulos con el precio así como indicaste en tu comentario, pero si solo necesitas obtener los articulos repetidos puedes usar solamente la consulta y subconsulta que están dentro de la CTE.

      Saludos.

      Me gusta

  8. buenas tardes quisiera de atu ayuda
    quisiera saber cuantas veces un cliente compro en dos sucursales diferente
    el mismo dia que el resultado me de algo asi

    usuarios fecha_actual sucursal
    jose hoy mexico
    jose hoy mexico

    Me gusta

    1. Hola Michel,

      Suponiendo que la tabla se llama «Compra» y tiene los siguientes registros:

      DatosMuestraCompras

      Puedes usar una consulta como la siguiente:

      Select Repetidos.Usuario, Repetidos.Fecha, Compra.Sucursal
      From ( Select Usuario, Fecha
      From Compra
      Group By Usuario, Fecha
      Having Count(*) > 1) As Repetidos Inner Join Compra
      On Compra.Usuario = Repetidos.Usuario And Compra.Fecha = Repetidos.Fecha

      Esta consulta arroja aquellos registros donde el usuario y la fecha son iguales pero la sucursal es diferente:

      ComprasMismoUsuarioMismaFechaDiferenteSucursal

      Me gusta

  9. Saludos Jhuvier,

    Quisiera saber como yo mediante una consulta devolver un registros por ser el mas completo repetido pero que tenga un unico id,
    me explico, si tengo una tabla que se llama productores, y tiene dos columnas 1-nombre_productor, 2-ID
    y dentro de los registros de la tabla tengo por ejemplo:

    NOMBRE_PRODUCTOR | ID
    juan | 01
    juan jose | 01
    juan jose jimenez | 01

    pero solo quiero traer a juan jose jimenez, como lo haria, teniendo en cuanto que hay registros unicos que no (no tienen el problema anterior).
    Me seria de gran ayuda por favor…

    Me gusta

    1. Hola Johan,

      Entiendo que es obtener el nombre del productor más completo, que en tu ejemplo sería Juan Jose Jimenez, si es correcta mi interpretación, te sugiero programar un algoritmo para eso porque es complejo determinar como se compone un nombre y si ese nombre realmente hace referencia a la misma persona, el motor de base de datos es limitado para ese tipo de cosas.

      Me gusta

  10. fijate que tengo este problema se repiten los campos y no se cual o por que se repiten
    este es el codigo
    SELECT dinterno.nombre,
    dinterno.a_paterno,
    dinterno.a_materno,
    dinterno.expediente,
    ddomicilios.calle as domi_interno,
    cnacionalidad.descripcion as nacionalidad,
    ddatos_generales.cmunicipio_nac_id as lugar_de_nacimiento,
    DATEDIFF(hour,ddatos_generales.fecha_nac,GETDATE())/8766 as edad,
    csexo.descripcion as sexo,
    cestado_civil.descripcion AS ESTADO_CIVIL,
    dreferencias.nombre as r_nombre,
    dreferencias.a_paterno as r_a_paterno,
    dreferencias.a_materno as r_a_materno,
    dreferencias.fotografia as r_fotografia,
    dreferencias.telefono as r_telefono,
    dreferencias.calle as r_calle,
    dreferencias.cp as r_cp,
    dreferencias.clocalidad_id as r_localidad,
    dreferencias.ccolonia_id as r_colonia,
    dreferencias.num_ext as r_num_ext,
    dreferencias.num_int as r_num_int,
    dreferencias.cmunipio_id as r_municipio,
    dreferencias.cparentesco_id as r_parentesco,
    dreferencias.cocupacion_id as r_ocupacion,
    dreferencias.csexo_id as r_sexo,
    dreferencias.fecha_nac as r_fecha_nac

    FROM dinterno
    left outer join destudio_socioeconomico on dinterno.id = destudio_socioeconomico.dingresos_id
    join ddatos_generales on dinterno.id = ddatos_generales.dinterno_id
    join dingresos on dinterno.id = dingresos.dinterno_id
    join cocupacion on cocupacion.id = ddatos_generales.cocupacion_id
    join ddomicilios on dinterno.id = ddomicilios.dinterno_id
    join cnacionalidad on cnacionalidad.id = ddatos_generales.cnacionalidad_id
    join cestado_civil on cestado_civil.id = ddatos_generales.cestado_civil_id
    join csexo on csexo.id = ddatos_generales.csexo_id
    join dts on dingresos.id = dts.dingresos_id
    join ccentro_penitenciario ON ccentro_penitenciario.id = dingresos.ccentros_penitenciario_id
    left outer join dusuarios on dusuarios.id = dinterno.dusuario_id
    left outer join dreferencias on dinterno.id = dreferencias.dinterno_id

    where dinterno.id = ddatos_generales.dinterno_id
    and ddatos_generales.id = (select max(id) from ddatos_generales a where a.dinterno_id = dinterno.id)

    Me gusta

    1. Hola Ramiro,

      Te agradezco si puedes por favor enviarme alguna captura de pantalla con los resultados que te arroja e indicando los registros repetidos que comentas ya que son muchas tablas y no sé que información haya en ellas que pueda estar causando el inconveniente. También te recomiendo dejar todos los «left outer join» de últimas para prevenir cruces inesperados de registros.

      Me gusta

      1. Hola Evilz,

        Para poder actualizar siempre debes poder distinguir el registro a actualizar, esto se hace generalmente por medio de la llave primaria de la tabla. Si la tabla no tiene llave primaria entonces se debe buscar alguna columna que permita diferenciar el registro a actualizar de los demás, por ejemplo, si se tiene una tabla «Usuario» sin llave primaria y con los siguientes usuarios repetidos (en 3 de las 4 columnas):

        Repetidos sin llave primaria

        Se puede usar la columna diferente, en este caso, la columna Edad para poder hacer la actualización:

        Update Usuario
        Set Identificacion = ‘67890’, Nombre = ‘Andrés’
        Where Identificacion = ‘12345’ And Edad = 22

        Ahora, si se da el caso en que absolutamente todos las columnas son iguales, lo más fácil es actualizar por medio del asistente gráfico. Para abrir el asistente se da clic derecho en el nombre de la tabla y se selecciona la opción «Edit Top 200 Rows»:

        Actualizar por asistente 1

        Esto abre una ventana con los 200 primeros registros de la tabla, en este caso nos muestra dos porque solo tenemos dos registros en ella. Dentro de esta ventana podemos editar directamente cada columna como queramos para cada registro y así realizamos la actualización deseada sin preocuparnos de como filtrar los registros duplicados:

        Actualizar por asistente 2

        Me gusta

  11. Buenas noches…
    Disculpen tengo un problema:
    tengo una tabla( tb_equipo_software) que tiene :
    id_equipo_software id_equipo id_configuracion_software
    —————— 1 ———- 1——————3
    —————— 2 ———– 1 —————- 11
    ——————-3 ———— 2——————3
    —————— 4 ———— 3 —————–11

    Entonces , necesito hacer una consulta que me muestre que equipo tiene el software 3 y 11 en este caso solo seria el 1
    el 2 no por que solo tiene el 3 y el 3 tampoco por tener solo el 11

    Select id_equipo from tb_equipo_software where id_configuracion_software in (3,11) group by id_equipo; / /Muestra todos ….1,2,3

    Gracias de antemano

    Me gusta

    1. Hola Brayan,

      Agrega la cláusula «HAVING» a la consulta para que te asegures de obtener solamente aquellos que aparezcan 2 o más veces puesto que son dos configuraciones de software por equipo las que estás buscando (3 y 11), además agrega al «GROUP BY» el campo «id_configuracion_software» para que realmente filtres por los que tienen las dos configuraciones y no una sola más de una vez (por ejemplo que no traiga un equipo que tenga la configuración 3 dos o más veces). La consulta quedaría de la siguiente manera:

      SELECT id_equipo
      FROM tb_equipo_software
      WHERE id_configuracion_software in (3,11)
      GROUP BY id_equipo, id_configuracion_software
      HAVING COUNT(id_equipo) >= 2

      Espero te sea de ayuda. Saludos!

      Me gusta

  12. Hola Jhuvier.

    Tengo un problema en un query, espero me puedas apoyar, el problema es el siguiente:

    Tengo este query:

    SELECT history.partno,
    history.serialno,
    history.ac_registr,
    history.location,
    history.vm,
    history.ac_registr,
    history.del_date,
    special.special
    FROM history
    JOIN part ON history.partno = part.partno
    JOIN part_special ON part.partno = part_special.partno
    JOIN special ON part_special.special = special.special
    WHERE history.partno = ‘BEGENX1B’
    GROUP BY history.partno,
    history.serialno,
    history.ac_registr,
    history.location,
    history.vm,
    history.ac_registr,
    history.del_date,
    special.special

    El cual me devuelve como resultado 27 filas de las cuales en el campo history.serialno algunas se repiten, lo que necesito es que no muestre los repetidos pero que mantenga al que tenga la fecha mas reciente el cual es el campo history.del_date.

    Viendo la ayuda que has brindado en los comentarios de arriba realice esto:

    SELECT history.partno,
    history.serialno,
    COUNT(*) as Repetidos,
    MAX(history.del_date),
    Min(history.ac_registr),
    MAX(history.location),
    MAX(history.vm),
    MAX(special.special)
    FROM history
    JOIN part ON history.partno = part.partno
    JOIN part_special ON part.partno = part_special.partno
    JOIN special ON part_special.special = special.special
    WHERE history.partno = ‘BEGENX1B’
    GROUP BY history.serialno,
    history.partno
    HAVING COUNT(*) > 0

    y me manda sin repetidos y deja el de la fecha mas actual pero los demas campos no coinciden con los datos que debería llevar.

    Espero me puedas apoyar.

    Saludos

    Me gusta

    1. Hola Sergio,

      Para el caso que expones debes usar una subconsulta la cual te ayuda a obtener la fecha más reciente del campo que estás buscando, en este caso el repetido «serialno». La consulta que deberías usar sería la siguiente:

      SELECT history.partno,
      history.serialno,
      history.ac_registr,
      history.location,
      history.vm,
      history.del_date,
      special.special
      FROM history
      JOIN part ON history.partno = part.partno
      JOIN part_special ON part.partno = part_special.partno
      JOIN special ON part_special.special = special.special
      WHERE history.partno = ‘BEGENX1B’
      AND history.del_date = (SELECT MAX(del_date) FROM history AS h WHERE h.serialno = history.serialno)

      Espero te sea de ayuda. Saludos!

      Me gusta

  13. Hola Jhuvier, tengo la siguiente consulta:

    tengo una tabla en SQL de control prenatal, cada paciente tiene 1 o más controles prenatales, en cada control prenatal le toman fecha del control, número del control, el peso, la talla, entre otros datos, yo necesito hacer una consulta que me devuelva por cada paciente, el peso, la talla etc del último control que tenga, entonces la condición sería él número de control más alto que tenga o la última fecha del control que tenga cada paciente.
    Hice la consulta de la siguiente manera:
    Seleccioné el IDpaciente, MAX(NumeroControl) as mayorControl, , hasta ahí muy bien, ejecuté la consulta y por cada ID me trajo el número de control más alto, pero cuando agregué en la consulta el campo Peso, cuando ejecuté la consulta se me repite el ID arrojándome todos los controles que tiene cada ID y yo solo necesito el último.

    Espero que me puedan ayudar, muchas gracias!!!

    Me gusta

    1. Hola Luisa,

      Para tu caso aplica la misma solución que le comenté a Sergio aquí, en tu caso quedaría de la siguiente manera:

      SELECT IDpaciente, NumeroControl, Peso, Talla
      FROM ControlPrenatal
      WHERE NumeroControl = (SELECT MAX(NumeroControl) FROM ControlPrenatal AS CP WHERE CP.IDpaciente = ControlPrenatal.IDpaciente)

      Saludos.

      Me gusta

      1. Hola Jhuvier, muchas gracias por tu pronta respuesta, hice lo que me dijiste:

        select dbo.Tbl_CPN.id, Tbl_CPN.Peso, dbo.Tbl_CPN.N_Control
        from Tbl_CPN where Tbl_CPN.N_Control=(select MAX(Tbl_CPN.N_Control) from
        Tbl_CPN as CP where cp.id=Tbl_CPN.id)

        y me arrojó el siguiente error:

        «No puede aparecer un agregado en la cláusula WHERE si no es en una subconsulta contenida en una cláusula HAVING o en una lista de selección, y siempre que la columna agregada sea una referencia externa»

        en donde está el problema?

        Me gusta

      2. Hola Luisa,

        Disculpa la demora; el inconveniente está en que estás usando la tabla principal dentro de la sub-consulta para seleccionar el máximo número de control, solo puedes acceder a la tabla principal dentro del WHERE o una clausúla HAVING. Entonces la solución es sencillamente que quites la referencia Tbl_CPN del agregado MAX o que referencies el campo con CP que es el alias que le diste a la tabla de la sub-consulta. Quedaría así dejando CP como referencia:

        select dbo.Tbl_CPN.id, Tbl_CPN.Peso, dbo.Tbl_CPN.N_Control
        from Tbl_CPN where Tbl_CPN.N_Control=(select MAX(CP.N_Control) from
        Tbl_CPN as CP where cp.id=Tbl_CPN.id)

        Saludos.

        Me gusta

  14. buenas noches,

    como puedo obtener los registros duplicados, he utilizado ese select pero de los datos duplicados me trae solo 1
    SELECT nibdua FROM s1neg GROUP BY nibdua HAVING count(*) > 1

    necesito por ejemplo que el resultado sea asi:
    cc nombre
    10305 pedro
    10305 carlos

    Gracias

    Me gusta

    1. Hola Robinson,

      Puedes usar la consulta de la siguiente manera para poder agregar el campo «nombre» a los registros duplicados por cédula:

      SELECT Repetidos.cc, s1neg.nombre
      FROM (SELECT cc FROM s1neg GROUP BY cc HAVING COUNT(*) > 1) AS Repetidos INNER JOIN s1neg
      ON s1neg.cc = Repetidos.cc

      Saludos.

      Me gusta

  15. yo tengo este problema tengo q coger las actividades q se repiten y mostrar la cantidad de gente q participo este mes y el pasado mes.
    Seria asi:
    Actividad | Mes Actual | Mes Pasado
    Asdf | 54845 | 62153

    me podias ayudar

    Me gusta

    1. Hola Ariel,

      Esta es la consulta que necesitas, consta de dos subconsultas, una para cada columna en la que se necesita calcular el número de personas que asistieron por mes actual y pasado:

      SELECT Nombre As Actividad,
      (SELECT COUNT(*)
      FROM Actividades AS A1
      WHERE A1.Nombre = Actividades.Nombre
      AND MONTH(A1.Fecha) = MONTH(GETDATE())
      ) AS MesActual,
      (SELECT COUNT(*)
      FROM Actividades AS A2
      WHERE A2.Nombre = Actividades.Nombre
      AND MONTH(A2.Fecha) = MONTH(DATEADD(MONTH, -1, GETDATE()))
      ) AS MesPasado
      FROM Actividades
      GROUP BY Nombre

      Espero te sea de ayuda. Saludos!

      Me gusta

  16. Hola, gracias por tu labor. En mi caso necesito fusionar 5 bases de datos en una, evidentemente la estructura es la misma pero de comenzar con los insert into select necesito en determinadas tablas detectar que el campo principal no esté repetido para estudiar qué hacer con el resto de información de esos registros, ya que no necesariamente todos los campos tendrán el mismo valor.

    En una hipotética tabla Clientes podemos obtener el campo Nombre de las diferentes bases de datos:

    NOMBRE | BDD
    Carlos | bd1
    José | bd1
    María | bd1
    Mónica | bd2
    José | bd2
    Alberto | bd2
    Pilar | bd3
    Carlos | bd3
    Pepe | bd4
    Jorge | bd4
    José | bd5
    Alberto | bd5
    Rosa | bd5

    Los registros que me gustaría obtener son los que aparecen como mínimo en dos bases de datos, para este ejemplo serían:

    NOMBRE | BDD
    Carlos | bd1
    Carlos | bd3
    José | bd1
    José | bd2
    José | bd5
    Alberto | bd2
    Alberto | bd5

    Usando CTE obtengo todos los registros:

    ;with bd1 as (select nombre, ‘BD1’ as bd from bbdd1.dbo.clientes)
    ,bd2 as (select nombre, ‘BD2’ as bd from bbdd2.dbo.clientes)
    ,bd3 as (select nombre, ‘BD3’ as bd from bbdd3.dbo.clientes)
    ,bd4 as (select nombre, ‘BD4’ as bd from bbdd4.dbo.clientes)
    ,bd5 as (select nombre, ‘BD5’ as bd from bbdd5.dbo.clientes)

    select nombre, bd
    from (
    select * from bd1 union all
    select * from bd2 union all
    select * from bd3 union all
    select * from bd4 union all
    select * from bd5 ) as todas

    Y luego he intentado sin éxito añadir funciones agregadas a ver si conseguía mi objetivo:

    group by nombre, bd
    having count(nombre)>0
    order by nombre

    Gracias por adelantado.

    Me gusta

  17. Es como si en uno de los ejemplos del problema planteado por la usuaria FERNANDA sobre los artículos científicos sólo quisiera que me aparecieran los registros que cumplen los tres primeros campos pero no el cuarto:

    a_volumen | a_fasciculo | a_paginicial | a_nombre
    1 | 2 | 10 | La guerra nunca acaba
    1 | 2 | 10 | Siendo jóvenes

    Realmente la primera Select sugerida en uno de los comentarios con «having count(*)>1» no devuelve ningún resultado, lo he probado, la segunda Select «having count(*)=0» los devuelve todos ya que no hay ninguna repetición de los cuatro campos idénticos.

    Me gusta

  18. Bueno, basándome en la respuesta que le diste al usuario JOSU creo que he conseguido lo que buscaba. Ejemplo con dos bases de datos buscando nombres de colores repetidos.

    ;with bd1 as (select nombre, ‘nombre_bd1’ as bd from nombre_bd1.dbo.colores)
    ,bd2 as (select nombre, ‘nombre_bd2’ as bd from nombre_bd2.dbo.colores)
    ,todas as (select * from bd1 union all select * from bd2)

    select repetidos.nombre, todas.bd
    from

    (select nombre
    from todas
    group by nombre
    having count(*)>1) as repetidos inner join todas on todas.nombre = repetidos.nombre

    order by repetidos.nombre

    Me gusta

  19. Hola buenas tardes tengo un problema se que me podras ayudar de antemano gracias por el apoyo
    el problema es que tengo varias tablas en donde logre crear una vista y juntar las tablas pero lo que quiero ahora es que al visualizar el resultado me marque o agregar un campo mas donde identifique que registros son los que se estan duplicando en esa vista.
    son Muchisimos campos pero para que tengas una idea manejo nombres completos RFC entre otros lo que me gustaria que al final de mi reporte me marque con un campo mas cuales son los que estan repetidos muchas gracias espero tu rewspuesta

    Me gusta

    1. Hola Alberto,

      Te puedo sugerir lo siguiente suponiendo que quieres obtener los duplicados de Campo1 de una vista:

      SELECT Campo1, Campo2, Campo3, Campo4, Subconsulta.Duplicados AS DuplicadosCampo1
      FROM View_1 INNER JOIN (SELECT Campo1, COUNT(*) AS Duplicados
      FROM View_1
      GROUP BY Campo1
      HAVING COUNT(*) > 1) AS SubConsulta
      ON Subconsulta.Campo1 = View_1.Campo1

      Saludos.

      Me gusta

    1. Hola Hashiro,

      Puedes usar una consulta como la siguiente:

      SELECT *
      FROM (SELECT Campo1, CampoDuplicado, CampoOrdenar, ROW_NUMBER() OVER(PARTITION BY CampoDuplicado ORDER BY CampoOrdenar) AS OrdenDuplicado
      FROM TuTabla) AS ConsultaBase
      WHERE OrdenDuplicado = 1

      Básicamente la magia está en la subconsulta que subdivide los registros que estén duplicados asignándoles un orden, en el caso de esta consulta de ejemplo se sabe que el campo por el que se duplican los registros es ‘CampoDuplicado’ y se quiere dar prioridad por ‘CampoOrdenar’, entonces si ejecutamos solamente la subconsulta tendríamos la siguiente información:

      Datos duplicados de ejemplo

      Como se puede observar se resaltan los registros duplicados en amarillo, más sin embargo todos quedan asignados con un orden que es al menos 1, los registros no se duplican más de dos veces razón por la cual el campo ‘OrdenDuplicado’ varían entre 1 y 2, si se duplicaran tres veces habría números del 1 al 3 por cada duplicado. Dicha subconsulta nos deja casi todo listo ya que la consulta principal lo que hace es filtrar por el campo ‘OrdenDuplicado’ para obtener solamente el primer registro por cada duplicado si así lo fuere, es decir, los registros NO duplicados simplemente quedan porque siempre van a tener un 1 en ese campo y de los duplicados solamente queda el que tenga el orden 1 según el campo ‘CampoOrdenar’ que fue el campo por el cual se ordenó por cada conjunto de duplicados.

      Espero te sea de ayuda. Saludos.

      Me gusta

  20. Saludos. He leído los comentarios anteriores pero «no doy con la tecla», a ver si puedes ayudarme. Necesito visualizar una tabla completa con varios campos, y que en una columna aparezcan todas las repeticiones de un campo en concreto (en este ejemplo, el campo ‘Nombre’). Algo así:

    MITABLA

    Nombre Apellidos Deporte NombresRepes
    ———————————————————————————
    Juan Pérez Parchis 3
    Juan Díaz Futbol 3
    Lola Pérez Remo 1
    Carmen Ronda Padel 2
    Juan Pérez Patines 3
    Carmen Manchego Vela 2

    Deben aparecer todos los registros, y una columna que indique el número de veces que se repite cada ‘Nombre’.

    Muchas gracias!

    Me gusta

Deja un comentario