Permintaan pekerjaan saya yang sebenarnya adalah gabungan internal, tetapi contoh sederhana ini dengan cross join tampaknya hampir selalu mereproduksi masalah.
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT NEWID() TEST_ID
) BB ( B )
Dengan gabungan internal saya, saya memiliki banyak baris yang saya tambahkan ke masing-masing GUID menggunakan fungsi NEWID (), dan untuk sekitar 9 dari 10 baris tersebut perkalian dengan tabel virtual 2-baris menghasilkan hasil yang diharapkan, hanya 2 salinan dari GUID yang sama, sedangkan 1 dari 10 akan menghasilkan hasil yang berbeda. Ini tidak terduga untuk sedikitnya dan memberi saya waktu yang sangat sulit untuk mencoba menemukan bug ini dalam skrip pembuatan data pengujian saya.
Jika Anda melihat kueri berikut menggunakan fungsi getdate dan sysdatetime yang juga non-deterministik, Anda tidak akan melihat ini, saya juga tidak. Saya selalu melihat nilai datetime yang sama di kedua baris hasil akhir.
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 )
Saat ini saya menggunakan SQL Server 2008 dan pekerjaan saya untuk saat ini adalah memuat baris saya dengan GUID ke dalam variabel tabel sebelum menyelesaikan skrip pembuatan data acak saya. Setelah saya memilikinya sebagai nilai dalam tabel yang bertentangan dengan tabel virtual, masalahnya hilang.
Saya punya solusi, tapi saya mencari cara untuk mengatasinya tanpa tabel atau variabel tabel aktual.
Saat menulis ini saya mencoba tanpa keberhasilan kemungkinan ini: 1) menempatkan newid () ke dalam tabel virtual bersarang:
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT TEST_ID
FROM (
SELECT NEWID() TEST_ID
) TT
) BB ( B )
2) membungkus newid () dalam ekspresi pemeran seperti:
SELECT CAST(NEWID() AS VARCHAR(100)) TEST_ID
3) membalik urutan tampilan tabel virtual dalam ekspresi gabungan
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS JOIN (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
4) menggunakan lintas tidak berkorelasi berlaku
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS APPLY (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
Tepat sebelum akhirnya memposting pertanyaan ini, sekarang saya mencoba ini dengan sukses tampaknya, sebuah salib berkorelasi berlaku:
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 )
Adakah yang punya solusi lain yang lebih elegan dan lebih sederhana? Saya benar-benar tidak ingin menggunakan lintas berlaku atau korelasi untuk perkalian baris sederhana jika saya tidak perlu.