Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   Insertar datos de un tabla en otra (https://www.clubdelphi.com/foros/showthread.php?t=95478)

MAXIUM 27-11-2021 02:03:57

Insertar datos de un tabla en otra
 
Hola a todos,

Tengo una consulta SQL que no se como completar y no sé cual sea la mejor opción por lo que recurro a vuestra sapiencia.

Tengo la TABLA_A y en esta se van almacenando los siguientes datos.

TABLA_A

Código:

| ID | NOMBRE |TIPO|ESTADO|
|----|--------|----|------|
|  1 |CABINA1 |  A |ACTIVO|
|  2 |CABINA1 |  B |ACTIVO|
|  3 |CABINA1 |  B | LISTO|
|  4 |CABINA1 |  A |  OK  |
|  5 |CABINA2 |  A | LISTO|
|  6 |CABINA2 |  B |ACTIVO|
|  7 |CABINA2 |  A |  OK  |
|  8 |CABINA2 |  B | LISTO|

No importa el orden de almacenamiento de los datos, solo quiero obtener el ULTIMO estado de cada cabina, por lo que uso la siguiente consulta SQL

Código SQL [-]
SELECT * FROM TABLA_A
WHERE ID IN (SELECT MAX(ID) FROM TABLA_A GROUP BY NOMBRE, TIPO);

Y obtengo
Código:

| ID | NOMBRE |TIPO|ESTADO|
|----|--------|----|------|
|  3 |CABINA1 |  B | LISTO|
|  4 |CABINA1 |  A |  OK  |
|  7 |CABINA2 |  A |  OK  |
|  8 |CABINA2 |  B | LISTO|

Lo que quiero es insertar todo en una segunda tabla, pero del siguiente modo
TABLA_B

Código:

| ID |NOMBRE  |TIPO|ESTADO|TIPO|ESTADO|
|----|--------|----|------|----|------|
|  1 |CABINA1 |  B | LISTO|  A |  OK  |
|  2 |CABINA2 |  A |  OK  |  B | LISTO|

En la TABLA_B la clave primaria es NOMBRE

Solo se me ocurre usar algo así para actualizar o inserta en esta tabla. Pero no se como integrar todo de una sola vez
Código SQL [-]
IF EXISTS(SELECT * FROM TABLA_B WHERE NOMBRE = NOMBRE)
    UPDATE 
    SET ...
    WHERE NOMBRE = NOMBRE
ELSE
    INSERT INTO
    ....

El motor es SQL Server.

mamcx 27-11-2021 18:48:50

Lo que describes y lo que pides no cuadra. Como va a ser "1 |CABINA1" el ultimo registro?

MAXIUM 27-11-2021 18:57:10

Cita:

Empezado por mamcx (Mensaje 544216)
Lo que describes y lo que pides no cuadra. Como va a ser "1 |CABINA1" el ultimo registro?

Bueno, el ID de la TABLA_B es independiente del ID de la TABLA_A por eso es 1

También debes fijaros en esta sentencia
Código SQL [-]
SELECT * FROM TABLA_A
WHERE ID IN (SELECT MAX(ID) FROM TABLA_A GROUP BY NOMBRE, TIPO);

Arroja esto
Código:

| ID | NOMBRE |TIPO|ESTADO|
|----|--------|----|------|
|  3 |CABINA1 |  B | LISTO|
|  4 |CABINA1 |  A |  OK  |
|  7 |CABINA2 |  A |  OK  |
|  8 |CABINA2 |  B | LISTO|

Por ende CABINA1 | B | LISTO es el último de los registros del tipo B de los CABINA1, lo mismo para el CABINA1 | A y resto de las cabinas

Considera una carga de datos de ejemplo como esta
Código:

| ID | NOMBRE |TIPO|ESTADO|
|----|--------|----|------|
|  1 |CABINA1 |  A |ACTIVO|
|  2 |CABINA1 |  B |ACTIVO|
|  3 |CABINA1 |  B | LISTO|
|  4 |CABINA1 |  A |  OK  |
|  5 |CABINA2 |  A | LISTO|
|  6 |CABINA2 |  B |ACTIVO|
|  7 |CABINA2 |  A |  OK  |
|  8 |CABINA2 |  B | LISTO|


bucanero 29-11-2021 09:42:30

hola a todos!!

Sin dar muchos mas detalles de la relación existente entre los datos nombre/tipo y suponiendo que el campo tipo solo pude tener dos valores distintos (A, B), una solución para obtener los datos que marcas en el ejemplo puede ser esta:

Código SQL [-]
SELECT d1.nombre,
       t1.id,
       t1.tipo,
       t1.estado,
       t2.id,
       t2.tipo,
       t2.estado
  FROM (                                                                    --
        -- agrupa por nombre los distintos id de estado
        SELECT NOMBRE, MIN(UID) AS m1, MAX(UID) AS m2
          FROM (                                                            --
                -- seleciona el ultimo id de cada grupo de nombre, estado
                SELECT NOMBRE, MAX(ID) AS UID
                  FROM TABLA_A
                GROUP BY NOMBRE, TIPO) d0
        GROUP BY nombre) d1
       LEFT JOIN tabla_a t1 ON t1.id = m1
       LEFT JOIN tabla_a t2 ON t2.id = m2

Si el campo TIPO puede variar entre mas de dos valores distintos, entonces esta solución ya no es correcta.


Este hilo esta en el foro de MS-SQL. Si realmente estas utilizando MSSQL como motor de BBDD puede utilizar también la opción PIVOT, que permite agrupar múltiples registros en varias columnas de un único registro

Neftali [Germán.Estévez] 29-11-2021 09:50:57

Unas preguntas...
¿Los tipos sólo pueden ser A y B?
En cuanto al resultado en la TABLE_B
Código:

| ID |NOMBRE  |TIPO|ESTADO|TIPO|ESTADO|
|----|--------|----|------|----|------|
|  1 |CABINA1 |  B | LISTO|  A |  OK  |
|  2 |CABINA2 |  A |  OK  |  B | LISTO|


No acabo de entender que las 2 columnas TIPO tengan los valores cambiados. Es decir, no sería más fácil rellenar inicialmente la TABLA_B con unos valores tal que así:
Código:

| ID |NOMBRE  |TIPO|ESTADO|TIPO|ESTADO|
|----|--------|----|------|----|------|
|  1 |CABINA1 |  A | NULL |  B | NULL |
|  2 |CABINA2 |  A | NULL |  B | NULL |


Y luego ir haciendo UPDATES, según CABINA y TIPO.

Tampoco se si los valores CABINA1 y CABINA2 son de ejemplo y puedes tener más... (CABINA3, CABINA4,...)

Al final, para estos casos con una lógica más completa, también puedes hacer una función o un SP, que vaya haciendo los pasos que describes.
La SELECT INICIAL, luego la agrupación, y luego el INSERT o UPDATE final con un CASE.

Casimiro Notevi 29-11-2021 10:38:26

De primer momento no contesté porque no se entiende correctamente el problema ni lo que se quiere conseguir.

mamcx 29-11-2021 16:29:04

Cita:

Empezado por MAXIUM (Mensaje 544217)
Bueno, el ID de la TABLA_B es independiente del ID de la TABLA_A por eso es 1

Esto en parte refleja el problema. Los datos no se pueden diferenciar y por ende es dificil deducir como van al final.

Te recomiendo que le agreges un sufijo a los datos que marcan las diferencias (ej: id_a, cabina1_b) donde sea el caso.

---

Por otro lado, lo mas probable es que estas tratando de meter un circulo en un cuadrado. Cual es la RAZON y el objetivo de lo que haces?


La franja horaria es GMT +2. Ahora son las 11:22:56.

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