Incorrect SQL generation in Join statement with subquery
See original GitHub issueI’ve faced with problem when create large query with subquery.
The query consists of two parts
var vendors = db.DocumentIt
.Where(w => w.IdDoc == idDoc)
.InnerJoin(db.SprShiPkis,
(it, sprShi) => it.Shi == sprShi.Shifr,
(it, sprShi) => new { it, sprShi })
.Where(w => w.sprShi.IdNumber.HasValue)
.InnerJoin(db.VBaseDocuments,
(all, whDocs) => all.it.IdBaseDoc == whDocs.IdDoc,
(all, whDocs) => new { all.it, all.sprShi, whDocs })
.GroupBy(w => w.sprShi.IdNumber)
.Select(w => new
{
IdNumber = w.Key,
IdDoc = w.Max(s => s.whDocs.IdDoc)
})
.LeftJoin(db.VBaseDocuments,
(all, doc) => all.IdDoc == doc.IdDoc,
(all, doc) => new { all.IdNumber, doc.IdVendor })
.LeftJoin(db.VBaseVendors,
(all, vnd) => all.IdVendor == vnd.IdVendor,
(all, vnd) => new { all, vnd })
.Select(w => new
{
IdNumber = w.all.IdNumber ?? 0,
UrAdres = w.vnd.UrAdres ?? string.Empty,
INN = w.vnd.INN ?? string.Empty,
Name = w.vnd.Naim ?? string.Empty
});
When I watch query, generated in this variable i have (as expected)
DECLARE @idDoc Int -- Int32
SET @idDoc = 14453
SELECT
Coalesce([all_1].[IdNumber], 0),
Coalesce([vendor].[UrAdres], N''),
Coalesce([vendor].[INN], N''),
Coalesce([vendor].[Name], N'')
FROM
(
SELECT
Max([whDocs].[IdDocument]) as [IdDocument],
[sprShi].[IdNumber] as [IdNumber]
FROM
[dbo].[DocumentIt] [w]
INNER JOIN [dbo].[SprShiPki] [sprShi] ON [w].[shi] = [sprShi].[shifr]
INNER JOIN [dbo].[vBaseDocument] [whDocs] ON [w].[IdBaseDocument] = [whDocs].[IdDocument]
WHERE
[sprShi].[IdNumber] IS NOT NULL AND [w].[IdDoc] = @idDoc
GROUP BY
[sprShi].[IdNumber]
) [all_1]
LEFT JOIN [dbo].[vBaseDocument] [doc] ON [all_1].[IdDocument] = [doc].[IdDocument]
LEFT JOIN [dbo].[vBaseVendor] [vendor] ON [doc].[IdVendor] = [vendor].[IdVendor]
It’s used in other query
var groupedKi = db.Documents
.Where(w => w.IdDoc == idDoc)
.InnerJoin(db.DocumentIt,
(document, it) => document.IdDoс == it.IdDoс,
(document, it) => new {document, it})
.Where(w => w.it.Shi != null && w.it.Shi.Trim() != string.Empty)
.LeftJoin(db.VPrice,
(all, price) => all.it.Shi == price.SHI,
(all, price) => new {all.document, all.it, price})
.LeftJoin(db.SprShiPkis,
(all, sprShiPki) => all.it.Shi == sprShiPki.Shifr,
(all, sprShiPki) => new {all.document, all.it, all.price, sprShiPki})
.LeftJoin(vendors,
(all, vendor) => all.sprShiPki.IdNumber == vendor.IdNumber,
(all, vendor) => new { all.document, all.it, all.price, all.sprShiPki, vendor })
.LeftJoin(db.SprNamePkis,
(all, sprNamePki) => all.sprShiPki.IdNumber == sprNamePki.IdNumber,
(all, sprNamePki) => new { all.document, all.it, all.price, all.sprShiPki, all.vendor, sprNamePki })
.LeftJoin(db.Resources,
(all, res) => all.it.Shi == res.Shifr,
(all, res) => new {all.document, all.it, all.price, all.sprShiPki, all.vendor, all.sprNamePki, res})
.LeftJoin(db.GrKis,
(all, grKi) => Convert.ToInt32(all.res.Grp) == grKi.GP,
(all, grKi) => new {all.document, all.it, all.price, all.sprShiPki, all.vendor, all.sprNamePki, all.res, grKi})
.LeftJoin(db.GrPKI1.Where(s => s.IdDoc == idDoc),
(all, grk1) => Convert.ToInt32(all.res.Grp) == grk1.GP,
(all, grk1) => new {all.document, all.it, all.price, all.sprShiPki, all.vendor, all.sprNamePki, all.res, all.grKi, grk1, Price = Convert.ToDouble(all.it.Cn)})
.GroupBy(w => new
{
w.price.GRP,
w.res.PGrp,
w.res.KName,
w.it.Cn,
w.vendor.Name,
w.vendor.INN,
w.vendor.UrAdres,
w.grk1.Koef,
w.grKi.GrName,
DocName = w.document.Name,
w.document.Nds,
w.document.Tzr,
w.document.Vozvr,
w.sprNamePki.Description,
w.sprNamePki.Name,
w.it.Npr,
w.it.Nt,
w.res.Grp,
w.sprNamePki.Import,
GP = w.grk1.GP,
w.Price
})
.Select(all => new RepDoc
{
Grp = Convert.ToInt32(all.Key.Grp),
PGrp = all.Key.PGrp,
Shi = string.Empty,
MatName = all.Key.Nameen,
Description = all.Key.Description,
KName = all.Key.KName,
Kol = all.Sum(w => w.it.Kol),
Price = all.Key.Price,
CdDocument = null,
VdNom = string.Empty,
NPARTNER = all.Key.Name,
INN = all.Key.INN,
UrAdres = all.Key.UrAdres,
Nch = all.Key.Npr + " " + all.Key.Nt,
NameDoc = string.Empty,
Nds = all.Key.Nds ?? 1,
Tzr = all.Key.Tzr ?? 0,
Vozvr = all.Key.Vozvr ?? 0,
CdUser = cdUser,
DescriptionGrp = all.Key.Description,
Import = all.Key.Import == 1,
FormGr = all.Key.GP
});
This generates the following SQL Statement
...
LEFT JOIN [dbo].[SprShiPki] [sprShiPki] ON [it].[shi] = [sprShiPki].[shifr]
LEFT JOIN (
SELECT
Coalesce([vendor].[Name], N'') as [c1],
Coalesce([vendor].[INN], N'') as [c2],
Coalesce([vendor].[UrAdres], N'') as [c3]
FROM
(
SELECT
Max([whDocs].[IdDocument]) as [IdDocument],
[sprShi].[IdNumber] as [IdNumber]
FROM
[dbo].[DocumentIt] [w_1]
INNER JOIN [dbo].[SprShiPki] [sprShi] ON [w_1].[shi] = [sprShi].[shifr]
INNER JOIN [dbo].[vBaseDocument] [whDocs] ON [w_1].[IdBaseDocument] = [whDocs].[IdDocument]
WHERE
[sprShi].[IdNumber] IS NOT NULL AND [w_1].[IdDoc] = @idDoc0
GROUP BY
[sprShi].[IdNumber]
) [all_1]
LEFT JOIN [dbo].[vBaseDocument] [doc] ON [all_1].[IdDocument] = [doc].[IdDocument]
LEFT JOIN [dbo].[vBaseVendor] [vendor] ON [doc].[IdVendor] = [vendor].[IdVendor]
) [t1] ON ([sprShiPki].[IdNumber] IS NULL AND Coalesce([all_1].[IdNumber], 0) IS NULL OR [sprShiPki].[IdNumber] = Coalesce([all_1].[IdNumber], 0))
LEFT JOIN [dbo].[SprNaimPki] [sprNaimPki] ON [sprShiPki].[IdNumber] = [sprNaimPki].[IdNumber]
...
but I’ve expected
...
LEFT JOIN [dbo].[SprShiPki] [sprShiPki] ON [it].[shi] = [sprShiPki].[shifr]
LEFT JOIN (
SELECT
Coalesce([all_1].[IdNumber], 0) as [IdNumber],
Coalesce([vendor].[Name], N'') as [c1],
Coalesce([vendor].[INN], N'') as [c2],
Coalesce([vendor].[UrAdres], N'') as [c3]
FROM
(
SELECT
Max([whDocs].[IdDocument]) as [IdDocument],
[sprShi].[IdNumber] as [IdNumber]
FROM
[dbo].[DocumentIt] [w_1]
INNER JOIN [dbo].[SprShiPki] [sprShi] ON [w_1].[shi] = [sprShi].[shifr]
INNER JOIN [dbo].[vBaseDocument] [whDocs] ON [w_1].[IdBaseDocument] = [whDocs].[IdDocument]
WHERE
[sprShi].[IdNumber] IS NOT NULL AND [w_1].[IdDoc] = @idDoc0
GROUP BY
[sprShi].[IdNumber]
) [all_1]
LEFT JOIN [dbo].[vBaseDocument] [doc] ON [all_1].[IdDocument] = [doc].[IdDocument]
LEFT JOIN [dbo].[vBaseVendor] [vendor] ON [doc].[IdVendor] = [vendor].[IdVendor]
) [t1] ON ([sprShiPki].[IdNumber] IS NULL AND [t1].[IdNumber] IS NULL OR [sprShiPki].[IdNumber] = [t1].[IdNumber])
LEFT JOIN [dbo].[SprNaimPki] [sprNaimPki] ON [sprShiPki].[IdNumber] = [sprNaimPki].[IdNumber]
[all_1] used out of scope instead [t1] in Join statement.
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (6 by maintainers)
Top Results From Across the Web
Incorrect Syntax Left Join subquery with aggregation
I'm trying to run the following query through SQL Server. I keep getting a incorrect syntax error near',' but I can't figure out...
Read more >Subqueries (SQL Server)
A subquery is a query that is nested inside a SELECT , INSERT , UPDATE , or DELETE statement, or inside another subquery....
Read more >"All joins can be rewritten to sub queries", is this statement ...
I would say the statement is false, though it's difficult to prove a negative. I don't believe a CROSS JOIN could be done...
Read more >Error when using UNION and correlated subquery with ...
I am trying to UNION some statements together. One statement uses a correlated subquery that contains an ORDER BY CLAUSE and when I...
Read more >Writing Subqueries in SQL
This lesson of the SQL tutorial for data analysis covers using subqueries in SQL with aggregate functions, conditional logic, and joins.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
agree, it’s true
with
F#
I just use tuples, but agree forC#
cases (they are most)can’t agree, however here I am talking only about
LINQ to Objects
usages, maybeLINQ to SQL
differsagree for this case totally
not sure about pain, will try to move in future, maybe you are right
Conclusion For my simplest queries
fluent
is not so bad, but for bigger ones it isReproduced, thanks. Trying to fix.