AYUDA CON INSERT SQL SERVE

mata.skt

Embrace Future, Embrace Bitcoin.
Se incorporó
16 Febrero 2020
Mensajes
1.482
Tengo una duda conceptual:

Si tiro esta query inserta los registros perfectamente

INSERT INTO TABLA2

SELECT A.*

FROM TABLA1 A WITH(NOLOCK)
LEFT JOIN
TABLA2 B WITH(NOLOCK)

ON A.CONT_ID=B.CONT_ID

WHERE
B.CONT_ID IS NULL
AND A.PERIODO>=202101

Pero si pongo el campo PERIODO antes del WHERE me tirar error de llave primaria duplicada

INSERT INTO TABLA2

SELECT A.*

FROM TABLA1 A WITH(NOLOCK)
LEFT JOIN
TABLA2 B WITH(NOLOCK)

ON A.CONT_ID=B.CONT_ID
AND A.PERIODO>=202101

WHERE
B.CONT_ID IS NULL

¿Por qué ocurre esto? No entiendo conceptualmente la diferencia :B
 
Solution
Where indica las condiciones de una consulta, siendo a.periodo >= 202101 parte de una condición.

Mientras que On te esta indicando la relación entre las dos tablas en este caso el cont_id.

Entonces esta tratando de agregar una condición en un campo donde se busca una relación.

No recuerdo si en el On puede tener más de una relación, ya que hace tiempo que no veo sql.

gab_tc

Miembro Activo
Se incorporó
22 Noviembre 2019
Mensajes
12
Where indica las condiciones de una consulta, siendo a.periodo >= 202101 parte de una condición.

Mientras que On te esta indicando la relación entre las dos tablas en este caso el cont_id.

Entonces esta tratando de agregar una condición en un campo donde se busca una relación.

No recuerdo si en el On puede tener más de una relación, ya que hace tiempo que no veo sql.
 
Upvote 1
Solution

ricm

Se incorporó
28 Agosto 2005
Mensajes
7.530
Creo que en el primer ejemplo el AND afecta al subquery select, y en el segundo, el AND afecta al insert. Por eso obtienes distintos resultados.
Agrega unos paréntesis y va a quedar más claro.
 
Upvote 0

clusten

ADMIN
Miembro del Equipo
ADMIN
Se incorporó
1 Julio 2007
Mensajes
6.157
Como bien indica gab_tc, Esta parte no puede ir en el “ON”:
“A.PERIODO>=202101”

Una validación simple para las query es que siempre tienen que tener sentido gramatical.

en el where si tiene sentido, pues estás dando condiciones qué hay que cumplir y tabla1.col2>202001 es una condición. En el on no pueden ir condiciones “abiertas”, solo relaciones entre las tablas
 
Upvote 0

Ariadno

Pajarito Viejo
Se incorporó
5 Diciembre 2008
Mensajes
658
Como bien indica gab_tc, Esta parte no puede ir en el “ON”:
“A.PERIODO>=202101”

Una validación simple para las query es que siempre tienen que tener sentido gramatical.

en el where si tiene sentido, pues estás dando condiciones qué hay que cumplir y tabla1.col2>202001 es una condición. En el on no pueden ir condiciones “abiertas”, solo relaciones entre las tablas
Yo sabía lo mismo, en mi conocimiento básico de sql
 
Upvote 0

Mesita

Capo
Se incorporó
3 Mayo 2007
Mensajes
100
si se pueden agregar condiciones en el join. La respuesta es más bien lo que indica @ricm
 
Upvote 0

mata.skt

Embrace Future, Embrace Bitcoin.
Se incorporó
16 Febrero 2020
Mensajes
1.482
si se pueden agregar condiciones en el join. La respuesta es más bien lo que indica @ricm
Claro, ahi quedo clarisimo:

The second will give those records plus any customers with no orders. The results set is very different depending on where you put the condition. (Select * is for example purposes only, of course you should not use this in production code.)

Si pones una fecha en el ON con un LEFT JOIN,te va a cruzar solo desde la fecha que pusiste,pero al ser LEFT JOIN te trae todos los registros .

Por lo tanto si lo combinas con un INSERT y un WHERE tabla2.ID IS NULL te estás trayendo registros que ya habias insertado anteriormente + los que no están.

Por eso me tira el error de llave primaria duplicada.

Vale compa!
 
Upvote 0

clusten

ADMIN
Miembro del Equipo
ADMIN
Se incorporó
1 Julio 2007
Mensajes
6.157
si se pueden agregar condiciones en el join. La respuesta es más bien lo que indica @ricm
de poder se puede, pero es inapropiado, salvo para casos muy rebuscados.
 
Upvote 0

mata.skt

Embrace Future, Embrace Bitcoin.
Se incorporó
16 Febrero 2020
Mensajes
1.482
Si trabajas con un INNER JOIN da igual si la fecha va en el ON o en el WHERE, el resultado es el mismo y el tiempo de ejecución no varia.


Para el caso de un LEFT JOIN no da lo mismo,entrega resultados distintos.

No recuerdo si en el On puede tener más de una relación, ya que hace tiempo que no veo sql.

Pueden haber todas las relaciones que quieras.

En tablas que se relacionan N:N una forma de transformar la relación a 1:1 es cruzar con 2 o más variables.

Otra forma puede ser agrupando ,pero ahi ya depende lo que necesites.
 
Última modificación:
Upvote 0

Ribosoma

Gold Member
Se incorporó
4 Enero 2006
Mensajes
3.184
Tengo una duda conceptual:

Si tiro esta query inserta los registros perfectamente



Pero si pongo el campo PERIODO antes del WHERE me tirar error de llave primaria duplicada



¿Por qué ocurre esto? No entiendo conceptualmente la diferencia :B

Solo decir que el "with(nolock)" no lo incluyas a menos que sea realmente necesario; puede generar resultados "extraños". Porque te puede tomar datos que al final no tuvieron commit.

Y el insert no lo hagas con * ; siempre hay que usar el listado de campos.
 
Upvote 0

mata.skt

Embrace Future, Embrace Bitcoin.
Se incorporó
16 Febrero 2020
Mensajes
1.482
Es que me dijeron textual :

"Si te pillamos haciendo consultas sin WITH(NOLOCK) ,te quitamos los permisos de acceso"

Al final lo escribo por costumbre ,pura inercia nomas
 
Upvote 0

Amenadiel

Ille qui nos omnes servabit
Fundador
OVERLORD
REPORTERO
Se incorporó
15 Enero 2004
Mensajes
18.398
Por supuesto que se puede añadir condiciones al join en vez de traerse un turro de tuplas que vas a descartar en el where. Para el query optimizer es el primer quick win antes de hacer introspección.

Lo que no se puede hacer, o no elegantemente, es agrupar en el join. Ese era el único caso donde era menos malo hacer una subquery. De todos modos hoy en día casi todos los motores soportan el bloque WITH.

Me estoy yendo pa otro lado. Lo importante es que todo eso aplica para el Select. Pienso que el insert tiene una condición no deterministica. Pero en realidad venía a comentar lo de arriba

Enviado desde mi HMA-L29 mediante Tapatalk
 
Upvote 0

Ribosoma

Gold Member
Se incorporó
4 Enero 2006
Mensajes
3.184
Es que me dijeron textual :

"Si te pillamos haciendo consultas sin WITH(NOLOCK) ,te quitamos los permisos de acceso"

Al final lo escribo por costumbre ,pura inercia nomas

jajajajaa... suele pasar.

A ver, el cuento corto es que si, nolock ayuda mejorar velocidad y evitar deadlocks; pero si por ejemplo necesitas integridad de datos lo mejore es no usarlo.
 
Upvote 0

frosstatx

AMD EX-NV Y LINUX FANBOY
Se incorporó
27 Junio 2008
Mensajes
473
Es que me dijeron textual :

"Si te pillamos haciendo consultas sin WITH(NOLOCK) ,te quitamos los permisos de acceso"

Al final lo escribo por costumbre ,pura inercia nomas
mejor SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED es mas elegante que un NOLOCK
 
Upvote 0

_V

The Hateful Wish
Se incorporó
11 Abril 2008
Mensajes
2.666
Tengo una duda conceptual:

Si tiro esta query inserta los registros perfectamente



Pero si pongo el campo PERIODO antes del WHERE me tirar error de llave primaria duplicada



¿Por qué ocurre esto? No entiendo conceptualmente la diferencia :B

en el segmento ON del join solo se deben poner condiciones que afecten a ambas tablas como ideal. Toda condición distintiva debe ir al final.

Para que veas la diferencia ejecuta solo los selects con ambas condiciones y revisa que devuelven.
 
Upvote 0

mata.skt

Embrace Future, Embrace Bitcoin.
Se incorporó
16 Febrero 2020
Mensajes
1.482
jajajajaa... suele pasar.

A ver, el cuento corto es que si, nolock ayuda mejorar velocidad y evitar deadlocks; pero si por ejemplo necesitas integridad de datos lo mejore es no usarlo.

Interesante.

Yo me he dado cuenta que cuando hago un "select top 10*" a una tabla que se está actualizando ya sea con INSERT O UPDATE no me arroja ningún resultado, se queda consultando eternamente.

Pero cuando le agrego el with (nolock) si me arroja resultados inmediatamente.

Pensé que servía para eso nomas el nolock xD ,pero ahora sé que puede que me arroje el resultado antiguo si es que estaba haciendo UPDATEpor ejemplo
 
Upvote 0
Subir