valores valor una tablas tabla sumar suma resultados restar numeros diferentes columnas campos campo mysql set temp database-table

valor - MySQL-Seleccione de una lista de números aquellos sin una contraparte en el campo de identificación de una tabla



sumar un valor a un campo en mysql (5)

Este es un problema que es bastante común: generar una relación sobre la marcha sin crear una tabla. Las soluciones SQL para este problema son bastante incómodas. Un ejemplo usando una tabla derivada:

SELECT n.id FROM (SELECT 2 AS id UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7) AS n LEFT OUTER JOIN foos USING (id) WHERE foos.id IS NULL;

Pero esto no se escala muy bien, porque puede tener muchos valores en lugar de solo seis. Puede resultar tedioso construir una larga lista con una UNION necesaria por valor.

Otra solución es mantener una tabla de propósito general de diez dígitos a la mano, y usarla repetidamente para múltiples propósitos.

CREATE TABLE num (i int); INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); SELECT n.id FROM (SELECT n1.i + n10.i*10 AS id FROM num AS n1 CROSS JOIN num AS n10 WHERE n1.i + n10.i*10 IN (2, 3, 4, 5, 6, 7)) AS n LEFT OUTER JOIN foos USING (id) WHERE foos.id IS NULL;

Muestro la consulta interna generando valores de 0..99 aunque esto no es necesario para este caso. Pero puede tener valores superiores a 10 en su lista. El punto es que con una tabla num , puede generar números grandes sin tener que recurrir a cadenas muy largas con una UNION por valor. Además, puede especificar la lista de valores deseados en un solo lugar, que es más conveniente y legible.

Tengo una lista de números, por ejemplo {2,4,5,6,7} Tengo una tabla, foos, con foos.ID, incluido decir, {1,2,3,4,8,9}

Me gustaría tomar mi lista de números y encontrarlos sin una contraparte en el campo ID de mi mesa.

Una forma de lograr esto sería crear una tabla de barras, cargada con {2,4,5,6,7} en el campo ID. Entonces, lo haría

SELECT bars.* FROM bars LEFT JOIN foos ON bars.ID = foos.ID WHERE foos.ID IS NULL

Sin embargo, me gustaría lograr esta tabla sans temp.

¿Alguien tiene alguna información sobre cómo podría suceder?


La solución de Alnitak (y la tuya) debería funcionar, y no puedo pensar en nada más que pueda funcionar solo en lenguaje SQL.

Pero aquí viene la pregunta: ¿cómo se pasa la lista de valores? ¿No es mejor manejar esto en el código de llamada, es decir, solicitar las identificaciones y compararlas en el código colling, que puede estar en un lenguaje más adecuado para este tipo de manipulaciones?


No puedo encontrar una solución a su problema preciso que no utiliza una tabla temporal, pero una forma alternativa de hacer su consulta utilizando una sub selección en lugar de una combinación es:

SELECT bars.* FROM bars WHERE bars.ID NOT IN (SELECT ID FROM foos)

Como los otros carteles que originalmente escribí:

SELECT * FROM foos WHERE foos.ID NOT IN (2, 4, 5, 6, 7)

pero luego me di cuenta de que esto está produciendo lo opuesto a lo que quieres.


Tuve un problema similar. Tenía un rango donde la clave primaria de auto incremento tenía algunos valores perdidos, así que primero encontré cuántos había: select count(*) from node where nid > 1962 . Comparando este número con el valor más alto, obtuve el número que falta. Luego ejecuté esta consulta: select n2.nid from node n1 right join node n2 on n1.nid = (n2.nid - 1) where n1.nid is null and n2.nid > 1962 Esto encontrará el número de no consecutivos registros faltantes No mostrará los consecutivos, y no estoy del todo seguro de cómo hacerlo, más allá de cambiar la cláusula ON para permitir una mayor latitud (lo que haría que la tabla JOIN sea sustancialmente más grande). En cualquier caso, esto me dio cinco resultados del total de siete desaparecidos, y los otros dos estaban garantizados para estar al lado de al menos uno de los cinco. Si le falta un número mayor, probablemente necesite otra forma de encontrar el que falta.


Si usa PHP, puede hacer que esto funcione sin crear tablas temporales.

SELECT ID FROM foos WHERE foos.ID IN (2, 4, 5, 6, 7)

Puede usar la función array_diff () de PHP para convertir esto al resultado deseado. Si su lista (2,4,5,6,7) está en una matriz llamada $ list y el resultado de la consulta anterior está en una matriz $ result, entonces

$no_counterparts = array_diff($list, $result);

... devolverá todos los números en su lista sin contrapartida en su tabla de base de datos. Si bien esta solución no realiza toda la operación dentro de la consulta, el procesamiento posterior que necesita hacer en PHP es mínimo para obtener lo que desea, y puede ser útil evitar tener que crear una tabla temporal.