Home > Software design >  SQL query on how do I get a random record from another table into a query on another table for every
SQL query on how do I get a random record from another table into a query on another table for every

Time:06-01

I am attempting to generate a random value from a table into a query being written against another table. There are two tables in the database (database name "TestDatabase"): a) [dbo].[Firstname_temp] - contains a list of firstnames (one column called "Firstname") b) [dbo].[Lastname_temp] - contains a list of last names (one column called "Lastname")

I am using the Lastname_temp table as a basis to bring in a random first name for each surname within the query. The Lastname table has been chosen as that has a larger number of records (80K) compared to the Firstname table which has about 5k.

I have written the following query, however it is now working as expected as it is bringing back the same random firstname for every surname.

SELECT Lastname,
(select top 1 Firstname from [dbo].[Firstname_temp] order by newid()) as Firstname
FROM [TestDatabase].[dbo].[Lastname_temp]

How can I bring back a random firstname for every lastname row rather than the same firstname appearing against them all?

Thanks in advance for your help.

CodePudding user response:

The problem is that NEWID() is only being executed once per the whole query. There is nothing to stop SQL Server doing that, as the subquery is not correlated. To fix this, you can correlate the subquery.

To explain:

NEWID() is a weird function. Although it is a side-effecting function, SQL Server does not guarantee that it will return a new value per output row, unless either the NEWID() call is directly in the main SELECT, or it is somehow correlated to the outer part of the query.

In your query, the inner subquery is not correlated, so the compiler understands that it can hoist it out of the rest of the query. To prevent that, you can force it to calculate it on each outer row, by putting in a redundant correlation. For example:

SELECT
  Lastname,
  (
    select top (1)
      Firstname
    from [dbo].[Firstname_temp] f
    where l.Lastname = l.Lastname   ''
    order by newid()
  ) as Firstname
FROM [TestDatabase].[dbo].[Lastname_temp] l
  • Related