Mi consulta de trabajo real era una unión interna, pero este simple ejemplo con unión cruzada casi siempre reproduce el problema.
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT NEWID() TEST_ID
) BB ( B )
Con mi unión interna, tuve muchas filas para las cuales agregué a cada uno un GUID usando la función NEWID (), y para aproximadamente 9 de cada 10 filas, la multiplicación con la tabla virtual de 2 filas produjo los resultados esperados, solo 2 copias de el mismo GUID, mientras que 1 de cada 10 produciría resultados diferentes. Esto fue inesperado, por decir lo menos, y me costó mucho tratar de encontrar este error en mi script de generación de datos de prueba.
Si echa un vistazo a las siguientes consultas utilizando también funciones getdate y sysdatetime no deterministas, no verá esto, no lo veo de todos modos: siempre veo el mismo valor de fecha y hora en ambas filas de resultados finales.
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT GETDATE() TEST_ID
) BB ( B )
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT SYSDATETIME() TEST_ID
) BB ( B )
Actualmente estoy usando SQL Server 2008 y mi trabajo por ahora es cargar mis filas con GUID en una variable de tabla antes de terminar mi script de generación de datos aleatorio. Una vez que los tengo como valores en una tabla en lugar de una tabla virtual, el problema desaparece.
Tengo una solución, pero estoy buscando formas de solucionarlo sin tablas o variables de tabla reales.
Mientras escribía esto, probé sin éxito estas posibilidades: 1) colocar el newid () en una tabla virtual anidada:
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT TEST_ID
FROM (
SELECT NEWID() TEST_ID
) TT
) BB ( B )
2) envolviendo el newid () dentro de una expresión de conversión como:
SELECT CAST(NEWID() AS VARCHAR(100)) TEST_ID
3) invertir el orden de aparición de las tablas virtuales dentro de la expresión de unión
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS JOIN (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
4) utilizando una aplicación cruzada no correlacionada
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS APPLY (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
Justo antes de finalmente publicar esta pregunta, ahora lo intenté con éxito, parece que se aplica una cruz correlacionada:
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS APPLY (
SELECT A
FROM (
SELECT 1 UNION ALL
SELECT 2
) TT ( A )
WHERE BB.B IS NOT NULL
) AA ( A )
¿Alguien tiene alguna otra solución más elegante y simple? Realmente no quiero usar la aplicación cruzada o la correlación para una simple multiplicación de filas si no es necesario.