How does this:
from c in Contacts
join a in Addresses
on c.Address_ID equals a.Address_ID
into Temp
from d in Temp.DefaultIfEmpty()
where c.First_Name.ToUpper().Contains("Pin".ToUpper())
select new { id = c.Contact_ID, value = (c.First_Name??"") + " " + (c.Last_Name??"") + " " + (c.Company_Name??""), FirstName = c.First_Name, LastName = c.Last_Name, AddressFull = d.Address_Full, Phone = c.Phone, Email = c.Email, CompanyName = c.Company_Name }
translate to this (using LinqPad)?
SELECT [t0].[Contact_ID] AS [id], ((((COALESCE([t0].[First_Name],#p1)) + #p2) + (COALESCE([t0].[Last_Name],#p3))) + #p4) + (COALESCE([t0].[Company_Name],#p5)) AS [value], [t0].[First_Name] AS [FirstName], [t0].[Last_Name] AS [LastName], [t1].[Address_Full] AS [AddressFull], [t0].[Phone], [t0].[Email], [t0].[Company_Name] AS [CompanyName]
FROM [Contact] AS [t0]
LEFT OUTER JOIN [Address] AS [t1] ON [t0].[Address_ID] = ([t1].[Address_ID])
WHERE UPPER([t0].[First_Name]) LIKE #p0
It seems that Temp.DefaultIfEmpty() == LEFT OUTER JOIN
What's the reasoning behind this syntax? Can someone please eloquently explain why?
This is not a magic incantation. You get the same semantics with pure LINQ to Objects. The join into is a left join already. It puts all matching items into a collection. There can be zero items or multiple.
from d in Temp.DefaultIfEmpty() would be an inner join because if there were no matching items we would drop the outer row. DefaultIfEmpty can now be used to add a "dummy null" to make this a left join.
This whole pattern is a little awkward but there's logic behind it.
Related
Ok, I have such SQL code:
DECLARE #documentId INT = 8
SELECT
i.[status] AS [status],
i.[barcode] AS [barcode],
i.[containerId] AS [containerTypeId],
(
SUM(ISNULL(lp.[Weight], 0) * il.[factCount]) +
ISNULL(lpt.[Weight], 0)
) AS [weight],
i.[comment] AS [comment]
FROM [Items] AS i WITH(NOLOCK)
LEFT JOIN [dbo].[ItemsLines] AS il WITH(NOLOCK) ON i.[id] = il.[itemsId]
LEFT JOIN [dbo].[LagerOptions] AS lp WITH(NOLOCK) ON lp.[lagerId] = il.[lagerId]
LEFT JOIN [dbo].[LagerOptions] AS lpt WITH(NOLOCK) ON lpt.[lagerId] = i.[containerId]
WHERE #documentId = i.[documentId]
GROUP BY i.[status], i.[barcode], i.[containerId], i.[comment], lpt.[Weight]
The most similar code I've written in LINQ is:
var lots = await (
from i in _dbContext.Items
join lpt in _dbContext.LagerOptions on i.ContainerId equals lpt.LagerId into lptTable
from lpt in lptTable.DefaultIfEmpty()
// The sum of all lagers for current lot
let lotWeight = (
from il in _dbContext.ItemsLines
join lp in _dbContext.LagerOptions on il.LagerId equals lp.LagerId into lpTable
from lp in lpTable.DefaultIfEmpty()
where il.ItemsId == i.Id
select (il.FactCount * lp.Weight.GetValueOrDefault(0))
).Sum()
where i.DocumentsId == documentId
select new
{
Status = i.Status,
Barcode = i.Barcode,
ContainerTypeId = i.ContainerId,
// total weight with container Weight
Weight = lotWeight + lpt.Weight.GetValueOrDefault(0),
//
Comment = i.Comment
}
).ToListAsync();
For SQL query the results can contain empty lots or lots with null-weight lagers (problem lagers) that makes "Weight" field of lot is equal NULL that helps detect problem lots.
But when I check the C# LINQ code EntityFramework create a COALESCE() function over SUM() function
and the query converted to SQL looks like this:
SELECT [t].[status] AS [Status], [t].[barcode] AS [Barcode], [t].[containerId] AS [ContainerTypeId], (
SELECT COALESCE(SUM([t0].[factCount] * COALESCE([l0].[Brutto], 0.0)), 0.0)
FROM [dbo].[ItemsLines] AS [t0]
LEFT JOIN [dbo].[LagerOptions] AS [l0] ON [t0].[lagerId] = [l0].[lagerId]
WHERE [t0].[itemsId] = [t].[id]) + COALESCE([l].[weight], 0.0) AS [Weight], [t].[comment] AS [Comment]
FROM [dbo].[Items] AS [t]
LEFT JOIN [dbo].[LagerOptions] AS [l] ON [t].[containerId] = [l].[lagerId]
WHERE [t].[documentId] = #__documentId_0
As a result, the weight of the problem lot will be equal to the container weight of this lot.
I can solve the problem with crutch methods, but I'm sure that there is a simple solution, which, unfortunately, I did not find.
I tryed to add different checks on null and rewrite the query for different JOIN patterns, but the main problem - EntityFramework create a COALESCE() function over SUM() function. And I don't know how to fix it in root. I work with C# EF approximately 1 month. EF 7.0.2
Help me, please.
!!EDITED
Correct LINQ query looks like this (Thank, Svyatoslav Danyliv):
var query =
from i in _dbContext.Items
join il in _dbContext.ItemsLines on i.Id equals il.ItemsId into ilj
from il in ilj.DefaultIfEmpty()
join lp in _dbContext.LagerOptions on il.LagerId equals lp.LagerId into lpj
from lp in lpj.DefaultIfEmpty()
join lpt in _dbContext.LagerOptions on i.ContainerId equals lpt.LagerId into lptj
from lpt in lptj.DefaultIfEmpty()
where i.DocumentsId == documentId
group new { lp, il, lpt } by new { i.Status, i.Barcode, i.ContainerId, i.Comment, lpt.Weight } into g
select new
{
g.Key.Status,
g.Key.Barcode,
ContainerTypeId = g.Key.ContainerId,
Weight = g.Sum(x => ((decimal?)x.lp.Weight) ?? 0 * x.il.FactCount) + g.Key.Weight ?? 0
g.Key.Comment,
};
But the query converted to SQL looks like this:
SELECT
[t].[status] AS [Status],
[t].[barcode] AS [Barcode],
[t].[containerId] AS [ContainerTypeId],
COALESCE(SUM(COALESCE([l].[weight], 0.0) * [t0].[factCount])), 0.0) +
COALESCE([l0].[weight], 0.0) AS [Weight],
[t].[comment] AS [Comment]
FROM [dbo].[Items] AS [t]
LEFT JOIN [dbo].[ItemsLines] AS [t0] ON [t].[id] = [t0].[itemsId]
LEFT JOIN [dbo].[LagerOptions] AS [l] ON [t0].[lagerId] = [l].[lagerId]
LEFT JOIN [dbo].[LagerOptions] AS [l0] ON [t].[containerId] = [l0].[lagerId]
WHERE [t].[documentsId] = #__documentId_0
GROUP BY [t].[status], [t].[barcode], [t].[containerId], [t].[comment], [l0].[weight]
EntityFramework create a COALESCE() function over SUM() function.
How to remove this?
This should equivalent LINQ query to your SQL. I do not understand why instead of grouping you have forced LINQ Translator to generate another query.
var query =
from i in _dbContext.Items
join il in _dbContext.ItemsLines on i.Id equals il.ItemsId into ilj
from il in ilj.DefaultIfEmpty()
join lp in _dbContext.LagerOptions on il.LagerId equals lp.LagerId into lpj
from lp in lpj.DefaultIfEmpty()
join lpt in _dbContext.LagerOptions on i.ContainerId equals lpt.LagerId into lptj
from lpt in lptj.DefaultIfEmpty()
where i.DocumentsId == documentId
group new { lp, il, lpt } by new { i.Status, i.Barcode, i.ContainerId, i.Comment, lpt.Weight } into g
select new
{
g.Key.Status,
g.Key.Barcode,
ContainerTypeId = g.Key.ContainerId,
Weight = g.Sum(x => ((double?)x.lp.Weight) ?? 0 * x.il.FactCount) + g.Key.Weight ?? 0
g.Key.Comment,
};
I am using Asp.NET & Entity Framework with SQL Server as Database, somehow I am getting this strange issue
I have this code:
var pricingInfo = (from price in invDB.Pricing.AsNoTracking()
join priceD in invDB.PricingDetail.AsNoTracking() on price.PricingId equals priceDtl.PricingId
join tagD in invDB.PricingTagDetail.AsNoTracking() on priceDtl.PricingDetailId equals tagDtl.PricingDetailId
join it in invDB.Item.AsNoTracking() on tagDtl.ItemId equals item.ItemId
join par in invDB.Party.AsNoTracking() on tagDtl.PartyId equals party.PartyId
join b in invDB.Brand.AsNoTracking() on tagDtl.BrandId equals brd.BrandId into t from brand in t.DefaultIfEmpty()
where tagDtl.AvailableQuantity > 0m && price.PricingNo == printNumber
select new
{
TagNo = tagDtl.TagNo,
SellingRate = tagDtl.SellingRate,
Quantity = tagDtl.AvailableQuantity ?? 0m,
ItemCode = item.Name,
UOMId = priceDtl.UOMId,
Brand = brand.BrandCode,
Supplier = party.PartyCode,
Offer = tagDtl.Offer
}).ToList();
Which generates the below sql query with a sub query, without where condition and it pulls out full records from a large volume data. This results to a heavy memory consumption and performance issues.
SELECT
[Filter1].[PricingId1] AS [PricingId],
[Filter1].[TagNo] AS [TagNo],
[Filter1].[SellingRate1] AS [SellingRate],
CASE WHEN ([Filter1].[AvailableQuantity] IS NULL) THEN cast(0 as decimal(18)) ELSE [Filter1].[AvailableQuantity] END AS [C1],
[Filter1].[Name] AS [Name],
[Filter1].[UOMId 1] AS [UOMId ],
[Extent6].[BrandCode] AS [BrandCode],
[Filter1].[PartyCode] AS [PartyCode],
[Filter1].[Offer] AS [Offer]
FROM
(
SELECT [Extent1].[PricingId] AS [PricingId1], [Extent1].[PricingNo] AS [PricingNo], [Extent2].[UnitOfMeasurementId] AS [UnitOfMeasurementId1], [Extent3].[TagNo] AS [TagNo], [Extent3].[BrandId] AS [BrandId1], [Extent3].[SellingRate] AS [SellingRate1], [Extent3].[AvailableQuantity] AS [AvailableQuantity], [Extent3].[Offer] AS [Offer], [Extent4].[Name] AS [Name], [Extent5].[PartyCode] AS [PartyCode]
FROM [PanERP].[Pricing] AS [Extent1]
INNER JOIN [PanERP].[PricingDetail] AS [Extent2] ON [Extent1].[PricingId] = [Extent2].[PricingId]
INNER JOIN [PanERP].[PricingTagDetail] AS [Extent3] ON [Extent2].[PricingDetailId] = [Extent3].[PricingDetailId]
INNER JOIN [PanERP].[Item] AS [Extent4] ON [Extent3].[ItemId] = [Extent4].[ItemId]
INNER JOIN [PanERP].[Party] AS [Extent5] ON [Extent3].[PartyId] = [Extent5].[PartyId]
WHERE [Extent3].[AvailableQuantity] > cast(0 as decimal(18))
) AS [Filter1]
LEFT OUTER JOIN [PanERP].[Brand] AS [Extent6] ON [Filter1].[BrandId1] = [Extent6].[BrandId]
WHERE ([Filter1].[PricingNo] = #p__linq__0) OR (([Filter1].[PricingNo] IS NULL) AND (#p__linq__0 IS NULL))
But When i change the condition
where tagDtl.AvailableQuantity > 0m
as a variable it creates another SQL query without nested select statement.
Here is the modified code
decimal availableQuantity = 0m;
var pricingInfo = (from price in invDB.Pricing.AsNoTracking()
join priceD in invDB.PricingDetail.AsNoTracking() on price.PricingId equals priceDtl.PricingId
join tagD in invDB.PricingTagDetail.AsNoTracking() on priceDtl.PricingDetailId equals tagDtl.PricingDetailId
join it in invDB.Item.AsNoTracking() on tagDtl.ItemId equals item.ItemId
join par in invDB.Party.AsNoTracking() on tagDtl.PartyId equals party.PartyId
join b in invDB.Brand.AsNoTracking() on tagDtl.BrandId equals brd.BrandId into t from brand in t.DefaultIfEmpty()
where tagDtl.AvailableQuantity > availableQuantity && price.PricingNo == printNumber
select new
{
TagNo = tagDtl.TagNo,
SellingRate = tagDtl.SellingRate,
Quantity = tagDtl.AvailableQuantity ?? availableQuantity,
ItemCode = item.Name,
UOMId = priceDtl.UOMId,
Brand = brand.BrandCode,
Supplier = party.PartyCode,
Offer = tagDtl.Offer
}).ToList();
and here is the SQL query without nested SQL statement.
SELECT
[Extent1].[PricingId] AS [PricingId],
[Extent3].[TagNo] AS [TagNo],
[Extent3].[SellingRate] AS [SellingRate],
CASE WHEN ([Extent3].[AvailableQuantity] IS NULL) THEN cast(0 as decimal(18)) ELSE [Extent3].[AvailableQuantity] END AS [C1],
[Extent4].[Name] AS [Name],
[Extent2].[UOMId ] AS [UOMId ],
[Extent6].[BrandCode] AS [BrandCode],
[Extent5].[PartyCode] AS [PartyCode],
[Extent3].[Offer] AS [Offer]
FROM [PanERP].[Pricing] AS [Extent1]
INNER JOIN [PanERP].[PricingDetail] AS [Extent2] ON [Extent1].[PricingId] = [Extent2].[PricingId]
INNER JOIN [PanERP].[PricingTagDetail] AS [Extent3] ON [Extent2].[PricingDetailId] = [Extent3].[PricingDetailId]
INNER JOIN [PanERP].[Item] AS [Extent4] ON [Extent3].[ItemId] = [Extent4].[ItemId]
INNER JOIN [PanERP].[Party] AS [Extent5] ON [Extent3].[PartyId] = [Extent5].[PartyId]
LEFT OUTER JOIN [PanERP].[Brand] AS [Extent6] ON [Extent3].[BrandId] = [Extent6].[BrandId]
WHERE ([Extent3].[AvailableQuantity] > #p__linq__0) AND (([Extent1].[PricingNo] = #p__linq__1) OR (([Extent1].[PricingNo] IS NULL) AND (#p__linq__1 IS NULL)))
If I move the where condition to the model definition as lambda expression, like this
from price in inventoryDb.Pricing.AsNoTracking().Where(c =>
c.PricingNo == printNumber))
then also it works fine.
Why is LINQ generating a nested Select? How can we avoid this?
Thanks in advance for your answers.
Well, I think you have answered your own question, on your comments. I will just try to clarify what is going on.
When you use a hard-coded constant, like 0m, the framework translates it into SQL keeping the value as a constant:
WHERE [Extent3].[AvailableQuantity] > cast(0 as decimal(18))
When you use a local variable, like “availableQuantity”, the framework creates a parameter:
([Extent3].[AvailableQuantity] > #p__linq__0)
I might be wrong, but, as I see, this is done in order to preserve the programmer’s goal when writing the code (constant = constant, variable = parameter).
And what about the subquery?
This is a query optimization logic (a bad one, probably, at least on this scenario). When you make a query using parameters, you might run it several times, but SQL Server will always use the same execution plan, making the query faster; when you use constants, each query need to be reevaluated (if you check SQL Server Activity Monitor, you will see that queries with parameters are treated as the same query, regardless the parameters values).
This way, in my opinion (sorry, I could not find any documentation about it), Entity Framework is trying to isolate the queries; the outer/generic one, that use parameters, and the inner/specific one, that use constants.
I would be happy if anyone could complement it with some Microsoft documentation about this subject…
I am fairly new to LINQ and I am struggling to make a multiple JOIN.
So, this is how my database structure looks like:
Now, how should my query look like, if I have a particular Grade and I want to select
{Student.IndexNo, GradeValue.Value}, but if there is no grade value for a particular grade and particular user, null should be returned (Left join)?
The trick to get a LEFT join is to use the DefaultIfEmpty() method:
var otherValue = 5;
var deps = from tbl1 in Table1
join tbl2 in Table2
on tbl1.Key equals tbl2.Key into joinGroup
from j in joinGroup.DefaultIfEmpty()
where
j.SomeProperty == "Some Value"
&& tbl1.OtherProperty == otherValue
select j;
Deliberately posting this in 2015 for newbies looking for solution on google hits. I managed to hack and slash programming my way into solution.
var projDetails = from r in entities.ProjekRumah
join d in entities.StateDistricts on r.ProjekLocationID equals d.DistrictID
join j in entities.ProjekJenis on r.ProjekTypeID equals j.TypeID
join s in entities.ProjekStatus on r.ProjekStatusID equals s.StatusID
join approvalDetails in entities.ProjekApproval on r.ProjekID equals approvalDetails.ProjekID into approvalDetailsGroup
from a in approvalDetailsGroup.DefaultIfEmpty()
select new ProjectDetailsDTO()
{
ProjekID = r.ProjekID,
ProjekName = r.ProjekName,
ProjekDistrictName = d.DistrictName,
ProjekTypeName = j.TypeName,
ProjekStatusName = s.StatusName,
IsApprovalAccepted = a.IsApprovalAccepted ? "Approved" : "Draft",
ProjekApprovalRemarks = a.ApprovalRemarks
};
Produces following SQL code internally
{SELECT [Extent1].[ProjekID] AS [ProjekID]
,[Extent1].[ProjekName] AS [ProjekName]
,[Extent2].[DistrictName] AS [DistrictName]
,[Extent3].[TypeName] AS [TypeName]
,[Extent4].[StatusName] AS [StatusName]
,CASE
WHEN ([Extent5].[IsApprovalAccepted] = 1)
THEN N'Approved'
ELSE N'Draft'
END AS [C1]
,[Extent5].[ApprovalRemarks] AS [ApprovalRemarks]
FROM [dbo].[ProjekRumah] AS [Extent1]
INNER JOIN [dbo].[StateDistricts] AS [Extent2] ON [Extent1].[ProjekLocationID] = [Extent2].[DistrictID]
INNER JOIN [dbo].[ProjekJenis] AS [Extent3] ON [Extent1].[ProjekTypeID] = [Extent3].[TypeID]
INNER JOIN [dbo].[ProjekStatus] AS [Extent4] ON [Extent1].[ProjekStatusID] = [Extent4].[StatusID]
LEFT JOIN [dbo].[ProjekApproval] AS [Extent5] ON [Extent1].[ProjekID] = [Extent5].[ProjekID]
}
Not even sure if I worded the question correctly, I have a huge sql server handicap, so this may be a simple thing I am not seeing. I have the following query:
select
stu.SyStudentId,
stu.FirstName,
stu.LastName,
stu.StartDate,
enr.AdProgramVersionId,
enr.AdCatalogYearId,
enr.GPA as CumGPA,
case when (stu.DateLstMod > enr.DateLstMod)
then stu.DateLstMod
else enr.DateLstMod
end as DateLstMod
from
SyStudent stu
inner join adenroll enr on enr.systudentid = stu.systudentid
inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
where systa.category in ('E','A')
and stu.sycampusid = 6
and
(
enr.AdProgramVersionId is null
or
(enr.AdProgramVersionId = '52' and enr.AdCatalogYearId='3')
or
(enr.AdProgramVersionId='53' and enr.AdCatalogYearId='3')
or
(enr.AdProgramVersionId='50' and enr.AdCatalogYearId='3')
or
(enr.AdProgramVersionId='51' and enr.AdCatalogYearId='3')
or
(enr.AdProgramVersionId='52' and enr.AdCatalogYearId='4')
or
(enr.AdProgramVersionId='53' and enr.AdCatalogYearId='4')
or
(enr.AdProgramVersionId='50' and enr.AdCatalogYearId='4')
or
(enr.AdProgramVersionId='51' and enr.AdCatalogYearId='4')
or
(enr.AdProgramVersionId='54' and enr.AdCatalogYearId='4')
)
The values in the nested 'and' clause can all be pulled from the database itself. The condition for the value is basically this:
Select adProgramVersionID
from AdEnroll
where AdCatalogYearId is not null
but if I try to put that in rather than the list of or clauses I get a different result set. Is there a way to accomplish what I need to do (replace the hard coded numbers with a retrieval of that number from the table)? Subqueries? Weird joins? Black magic?
This is the code that I am trying to replace with just a straight sql query:
var query = #"
select
stu.SyStudentId,
stu.FirstName,
stu.LastName,
stu.StartDate,
enr.AdProgramVersionId,
enr.AdCatalogYearId,
enr.GPA as CumGPA,
case when (stu.DateLstMod > enr.DateLstMod)
then stu.DateLstMod
else enr.DateLstMod
end as DateLstMod
from
SyStudent stu
inner join adenroll enr on enr.systudentid = stu.systudentid
inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
where systa.category in ('E','A')
and stu.sycampusid = 6
and
(
enr.AdProgramVersionId in
("
+ String.Join(",", dc.CatalogPrograms.Where(cp => cp.Catalog.CvAdCatalogYearId == null).Select(cp => cp.CvAdProgramVersionId)) + #"
)
or
(";
// get the students in program versions that use catalogs
var andClauses = new List<string>();
foreach (var catProg in dc.CatalogPrograms.Where(cp => cp.Catalog.CvAdCatalogYearId != null))
andClauses.Add("(enr.AdProgramVersionId=" + catProg.CvAdProgramVersionId + " and enr.AdCatalogYearId=" + catProg.Catalog.CvAdCatalogYearId + ")");
query += string.Join("\n or", andClauses) + #"
)
)";
The reason I want to get rid of this code is I do not want to mix linq-to-sql in the new solution, I am using this as an import to a new database design altogether that will be using EF as the ORM.
You can incorporate the AdEnroll into your FROM clause and then simplify the WHERE as follows. My edits are in CAPS.
from
SyStudent stu
inner join adenroll enr on enr.systudentid = stu.systudentid
inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
LEFT OUTER JOIN ADENROLL AE ON ENR.ADPROGRAMVERSIONID = AE.ADPROGRAMVERSIONID
where systa.category in ('E','A')
and stu.sycampusid = 6
and
(
enr.AdProgramVersionId is null
OR
AE.ADCATALOGYEARID IS NOT NULL
)
As a result of this query I have a table:
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
Now I need to use the result of this table in the next query:
select PriceListItem.ProductExternalId, #id.Id, #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from [#id]
inner join [Product] on Product.ItemId = #name and Product.InstanceId = #id.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId
instead of '#id' I should use data from the table with name= id, and instead of '#name' I should use data from the table with name= name
Standard SQL way, works in most RDBMS
select PriceListItem.ProductExternalId, #id.Id, #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from
(
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
)
X
inner JOIN
[#id] ON X.id = #id.id --change here as needed
inner join [Product] on Product.ItemId = #name and Product.InstanceId = #id.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId*
Since you're on SQL 2K8 you can use a CTE:
-- You may need a ; before WITH as in ;WITH
WITH FirstQuery AS (
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
)
select PriceListItem.ProductExternalId,
FQ.Id,
-- Neither of these are in your FirstQuery so you can not use them
-- #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from FirstQuery FQ
inner join [Product] on Product.ItemId = FQ.name
and Product.InstanceId = FQ.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId;
From the queries alone it's tough to tell how you plan to JOIN them, but this will allow you to make use of the first query in the subsequent one.
Looks like you have some syntax errors in your second query - #id.id?
select i.id, o.[name] from Item i
into #temp_table
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
Now you can use #temp_table as you want :)