BruceyBandit
BruceyBandit

Reputation: 4324

Understanding nested select queries

Have a question in regards to what was a select into query that I am changing into an insert into query with a select and I just wanted somebody to help me understand the query and know why the only fields in the select it wants are only certain fields.

Ok so below is a create table statement I have written for the temp tables '#Infants' and '#MobileBookings'.

create table #MobileBookings
        (
        Reference nvarchar(50), 
        CreatedDate datetime, 
        FirstName nvarchar(50), 
        Surname nvarchar(50), 
        PersonTypeId int, 
        PackageId int, 
        PersonId int, 
        ProductId int, 
        StatusId smallint   
        )

create table #Infants
        (
        Reference nvarchar(50), 
        CreatedDate datetime, 
        FirstName nvarchar(50), 
        Surname nvarchar(50), 
        PersonTypeId int, 
        ProductPersonId int, 
        StatusId smallint,
        FlightNumber nvarchar(50), 
        DepartureDateTime datetime, 
        SectorName nvarchar(50), 
        BoundID varchar(8)
        )

Now what I have in the existing code (that I didn't write but trying to manipulate by including insert into instead of what previously was select into to remove certain warnings.

insert into #Infants (
Reference, CreatedDate, FirstName, Surname, 
PersonTypeId, ProductPersonId, StatusId, FlightNumber, 
DepartureDateTime, SectorName, BoundID
)
select * from
(
    select  
    x.Reference, x.CreatedDate, x.FirstName, x.Surname, 
    x.PersonTypeId, pp.ProductPersonId, pp.StatusId as 'ProductPersonStatusID', null as 'DependantPPID',
            fl.FlightNumber, 
    fl.DepartureDateTime, fs.SectorName, iif(fr.BoundID=0,'OutBound','InBound') as 'FlightBound'
    from    #MobileBookings as x
            inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
            inner join Reservations_Live.dbo.FlightReservation as fr with (nolock) on fr.ProductId = x.ProductId
            inner join Reservations_Live.dbo.Flight as fl with (nolock) on fl.FlightId = fr.FlightId
            inner join Reservations_Live.dbo.FlightSector as fs with (nolock) on fs.FlightSectorId = fl.FlightSectorId
            INNER join
                (
                    select  x.PackageId as 'PKID', frp.DependantProductPersonId as 'DepPPID', frp.ProductPersonID as 'CarerPPID', 
                            pp.StatusId as 'CarerPPST'
                    from    #MobileBookings as x
                            inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
                            inner join Reservations_Live.dbo.FlightReservationPassenger as frp with (nolock) on frp.ProductPersonID = pp.ProductPersonId
                    where   x.PersonTypeId = 1
                    and     pp.StatusId = 3
                    and     frp.DependantProductPersonId is not null
                )
                as car on car.PKID = x.PackageId and car.DepPPID = pp.ProductPersonId
    where   x.StatusId < 7
    and     x.PersonTypeId = 3
    and     pp.StatusId = 2
    and     fl.FlightStatusId < 3
    and     fl.DepartureDateTime > GETUTCDATE()
)   as inf;
set @ActualRowCount = @@rowcount;

Ok so in visual studio, if I hover over the * in the select statement, it displays a hover box that shows the only fields it requires to select:

Reference (nvarchar, null),
CreatedDate (datetime, null),
FirstName (nvarchar, null),
Surname (nvarchar, null),
PersonTypeId (int, null),
ProductPersonStatusID(, null),
DependantPPID(void, not null),
FlightBound (, null) 

I'm assuming I need to change my create table and insert into to only include these relevant fields above but what I want to know is how come it only wants to select these fields and not include any other relevant fields?

Also in regards to the ProductPersonStatusID and DependantPPID which is based on the 'StatusID', are they actually displayed as two columns in the final output, meaning the create table will need to include both these columns and they both also need to be included in the insert into? StatusId is an int so if this is the case, I'm assuming 'ProductPersonStatusID' should be set as an int but DependantPPID should be set as a null in the CREATE statement?

UPDATE:

Hopefully I'm in the right section but included the subquery for inf as stated in the comment:

update  pp
set     pp.StatusId = 3
output 'ProductPerson', 'ProductPersonId', inserted.ProductPersonId,
Core.updXMLFragment('StatusId',inserted.StatusId,deleted.StatusId)
into    @OutputList
from    Reservations_Live.dbo.ProductPerson as pp
inner join #Infants as inf on inf.ProductPersonId = pp.ProductPersonId;
set     @UpdateRowCount = @@Rowcount;

Just to make sure, I have changed the create table and the insert into statement to the follow, which I hope is correct:

create table #Infants
(
Reference nvarchar(50), 
CreatedDate datetime, 
FirstName nvarchar(50), 
Surname nvarchar(50), 
PersonTypeId int, 
ProductPersonStatusID int, 
DependantPPID int,
FlightBound varchar(8)
);

--

insert into #Infants (Reference, CreatedDate, FirstName, Surname, PersonTypeId, ProductPersonStatusID, DependantPPID, FlightBound)
    select * from...

Upvotes: 1

Views: 104

Answers (1)

Nick.Mc
Nick.Mc

Reputation: 19184

I suggest you remove the select * altogether. This is bad practice. There is rarely a good reason to use SELECT * As it was you had a couple of fields mismatched.

Note how the order of fields in the INSERT needs to match the order of fields in the SELECT. That's why I like to spread them across a few lines so I can match them up.

Also WITH (NOLOCK) is not magic go fast switch but that's for another post....

insert into #Infants (
Reference, CreatedDate, 
FirstName, Surname, 
PersonTypeId, ProductPersonId, 
StatusId, FlightNumber, 
DepartureDateTime, SectorName, 
BoundID
)
select  
x.Reference, x.CreatedDate, 
x.FirstName, x.Surname, 
x.PersonTypeId, pp.ProductPersonId, 
pp.StatusId as [ProductPersonStatusID], fl.FlightNumber,
fl.DepartureDateTime, fs.SectorName, 
iif(fr.BoundID=0,'OutBound','InBound') as [FlightBound]
from    #MobileBookings as x
inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
inner join Reservations_Live.dbo.FlightReservation as fr with (nolock) on fr.ProductId = x.ProductId
inner join Reservations_Live.dbo.Flight as fl with (nolock) on fl.FlightId = fr.FlightId
inner join Reservations_Live.dbo.FlightSector as fs with (nolock) on fs.FlightSectorId = fl.FlightSectorId
INNER join
                (
                    select  x.PackageId as 'PKID', frp.DependantProductPersonId as 'DepPPID', frp.ProductPersonID as 'CarerPPID', 
                            pp.StatusId as 'CarerPPST'
                    from    #MobileBookings as x
                            inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
                            inner join Reservations_Live.dbo.FlightReservationPassenger as frp with (nolock) on frp.ProductPersonID = pp.ProductPersonId
                    where   x.PersonTypeId = 1
                    and     pp.StatusId = 3
                    and     frp.DependantProductPersonId is not null
                )
                as car on car.PKID = x.PackageId and car.DepPPID = pp.ProductPersonId
    where   x.StatusId < 7
    and     x.PersonTypeId = 3
    and     pp.StatusId = 2
    and     fl.FlightStatusId < 3
    and     fl.DepartureDateTime > GETUTCDATE()

Upvotes: 1

Related Questions