How can I convert this below code from SQL to Linq
SELECT CF.CustomerProfileId,CF.Salutation,CF.Gender,CF.LastName,
CF.DateOfBirth,AD.Line1,AD.Line2,AD.Line3,AD.Line4,AD.Line5,
AD.Country,AD.ElectronicAddressDesc,NCIType.NationalCustomerIdentifierTypeDesc,
NCI.NationalCustomerIdentifier from CustomerProfile CF
left join Address AD on CF.CustomerProfileId = CF.CustomerProfileId
left join NationalCustomerIdentifiers NCI on CF.CustomerProfileId = NCI.CustomerProfileId
left join NationalCustomerIdentifierType NCIType on NCI.NationalCustomerIdentifierTypeId = NCIType.NationalCustomerIdentifierTypeId
where CF.CustomerProfileId = #CustomerProfileid and CF.Version = #Version
You need to make several left joins in LINQ. This is possible though will look not very good (linq is not very comfortable when dealing with joins other than inner).
Here is a microsoft example of left join in linq It only joins two tables but you can extend it. And if you don't like how the result looks - than make a view or an sproc.
Related
I'm working with some views in an old HR system that frequently puts a number of joins together with the 'ON' part of the joins not coming until the end. Why would someone do it in this way and is there some advantage to it? I find it quite confusing when there is a large number of joins in it. I couldn't quite describe the situation in a web search well enough to help me.
SELECT
ExportTypeIdNo = et.ExportTypeIdNo,
ExportDataStoredProcedureIdNo = et.ExportDataStoredProcedureIdNo,
ExportDataStoredProcedure = sp1.Name,
ExportFileStoredProcedureIdNo = et.ExportFileStoredProcedureIdNo,
ExportFileStoredProcedure = sp2.Name
FROM tSTORED_PROCEDURES sp2 INNER JOIN
(tSTORED_PROCEDURES sp1 INNER JOIN
(tEXPORT_TYPES et INNER JOIN tTYPE_CODES tc
ON et.ReportingTreeIdNo = tc.TypeCodeIdNo)
ON sp1.StoredProcedureIdNo = et.ExportDataStoredProcedureIdNo)
ON sp2.StoredProcedureIdNo = et.ExportFileStoredProcedureIdNo
This code is just an example of what this type of join looks like.
There is no good reason to do this. With inner join, any ordering of the joins is equivalent. Almost everyone would agree that the following is simpler to follow and maintain:
FROM tEXPORT_TYPES et INNER JOIN
tTYPE_CODES tc
ON et.ReportingTreeIdNo = tc.TypeCodeIdNo INNER JOIN
tSTORED_PROCEDURES sp1
ON sp1.StoredProcedureIdNo = et.ExportDataStoredProcedureIdNo INNER JOIN
tSTORED_PROCEDURES sp2
ON sp2.StoredProcedureIdNo = et.ExportFileStoredProcedureIdNo
There are some arcane situations where rearranging outer joins is not exactly equivalent. In general, though, inner joins followed by left joins is sufficient for almost all the queries that I write.
As to why someone would write the joins this way? I can only speculate. My most likely reason is that they were using ,s in the from clause and simply grew to prefer having all the tables referenced before the conditions connecting them.
I normalized my data and have been trying to display data across multiple tables. I'm fairly new to SQL, so please bear with me.
What I'm trying to do is display tasks that haven't been assigned to a project yet, but contain data from various tables such as project title, company, etc (Using a LEFT JOIN and a WHERE clause).
The original code which works:
SELECT Tasks.ID, Projects_Tasks.ProjectID
FROM Tasks LEFT JOIN Projects_Tasks ON Projects_Tasks.TaskID = Tasks.ID
WHERE Projects_Tasks.ProjectID IS NULL;
The nested joins code (that doesn't work):
SELECT Tasks.ID, Projects.ProjectTitle, ProjectManagers.FirstName, ProjectManagers.LastName, Companies.Company
FROM ((((Tasks
LEFT JOIN Projects_Tasks ON Projects_Tasks.TaskID = Tasks.ID)
INNER JOIN Projects_Tasks ON Projects_Tasks.ID = Projects.ID)
INNER JOIN Projects ON Projects.ID = Projects_Tasks.ProjectID)
INNER JOIN ProjectManagers ON ProjectManagers.ID = Projects.ProjectManagerID)
INNER JOIN Companies ON Companies.ID = ProjectManagers.CompanyID
WHERE Projects_Tasks.ProjectID IS NULL;
I've tried numerous combinations, but I just can't get it to work. I've tried reversing the order of my nested joins (in case it executes from bottom to top) and I've tri
I don't enjoy writing SQL statements.The good thing about Access though is it can make your SQL statements for you in Queries
Using Query Builder:
Select the tables Project_Tasks & Project_Managers & all other tables
you want to display data
Select all the relevant data fields you want to display
Where you have the 'ProjectID' field, the Criteria section needs to have "Is Null" (don't put the quotation marks though)
Then, save the query, and run it. (You can probably just use that query, or otherwise strip out the SQL statement)
Good luck!
I have a query which works, goes like this:
Select
count(InsuranceOrderLine.AntallPotensiale) as potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name
This query over returns what I need, but when I try to add more table (InsuranceOrder) to be able to get the regardingUser column, then all the count values are way high.
Select
count(InsuranceOrderLine.AntallPotensiale) as Potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori,
RegardingUser
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory, InsuranceSalesLead
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name,RegardingUser
Thanks in advance
You're adding one more table to your FROM statement, but you don't specify any JOIN condition for that table - so your previous result set will do a FULL OUTER JOIN (cartesian product) with your new table! Of course you'll get duplication of data....
That's one of the reasons that I'm recommending never to use that old, legacy style JOIN - do not simply list a comma-separated bunch of tables in your FROM statement.
Always use the new ANSI standard JOIN syntax with INNER JOIN, LEFT OUTER JOIN and so on:
SELECT
count(iol.AntallPotensiale) as Potensiale,
COUNT(iol.AntallSolgt) as Solgt,
ip.Name,
ipc.Name as Kategori,
isl.RegardingUser
FROM
dbo.InsuranceOrderLine iol
INNER JOIN
dbo.InsuranceProduct ip ON iol.FKInsuranceProductId = ip.InsuranceProductID
INNER JOIN
dbo.InsuranceProductCategory ipc ON ip.FKInsuranceProductCategory = ipc.InsuranceProductCategoryID
INNER JOIN
dbo.InsuranceSalesLead isl ON ???????? -- JOIN condition missing here !!
When you do this, you first of all see right away that you're missing a JOIN condition here - how is this new table InsuranceSalesLead linked to any of the other tables already used in this SQL statement??
And secondly, your intent is much clearer, since the JOIN conditions linking the tables are where they belong - right with the JOIN - and don't clutter up your WHERE clauses ...
It looks like you added the table join which slightly multiplies count of rows - make sure, that you properly joining the table. And be careful with aggregate functions over several joined tables - joins very often lead to duplicates
I have the following T-SQL query (a simple test case) running fine in MS SQL but cannot get the equivalent query in MS Access (JET-SQL). The problem is the additional criteria in the LEFT JOIN. How can I do this in MS Access?
T-SQL:
SELECT * FROM A
LEFT OUTER JOIN B ON A.ID = B.A_ID
AND B.F_ID = 3
JET-SQL (what I have so far but crashes Access!):
SELECT * FROM dbo_A
LEFT JOIN dbo_B ON (dbo_A.ID = dbo_B.A_ID AND dbo_B.F_ID = 3)
You need to use a subselect to apply the condition:
SELECT *
FROM dbo_A LEFT JOIN
[SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3]. AS dbo_B
ON dbo_A.ID = dbo_B.A_ID;
If you're running Access with "SQL 92" compatibility mode turned on, you can do the more standard:
SELECT *
FROM dbo_A LEFT JOIN
(SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3) AS dbo_B
ON dbo_A.ID = dbo_B.A_ID;
Do you need this to be editable in Access? If not, just use a passthrough query with the native T-SQL. If so, I would likely create a server-side view for this, and I'd especially want to move it server-side if the literal value is something you would parameterize (i.e., the F_ID=3 is really F_ID=N where N is a value chosen at runtime).
BTW, I write these subselect derived table SQL statements every single day while working in Access. It's not that big a deal.
Do you get an error message when it crashes or does it just lock up? Judging by the dbo_B name I'm going to guess that these are linked tables in Access. I believe that when you do a join like that Access doesn't tell SQL server that it needs the result of the join, it says, "Give me all of the rows of both tables" then it tries to join them itself. If the tables are very large this can cause the application to lock up.
You're probably better off creating a view on SQL Server for what you need.
I think ms access expect to both tables name in each section of Joins ON clause. As a trick this work for me:
SELECT * FROM A
LEFT OUTER JOIN B ON A.ID = B.A_ID
AND B.F_ID = IIF(True, 3, A.ID)
A.ID or any other else field from table A
That last condition technically isn't a join but a comparison to a literal value. Put it in a WHERE clause:
SELECT *
FROM a LEFT OUTER JOIN b ON a.ID = b.a_id
WHERE b.f_id = 3;
Since SQLite does not support RIGHT OUTER JOINS I pose the following challenge (read: invitation to do my work for me):
Refactor this query so it no longer utilises SQLite-unsupported constructs like RIGHT/FULL OUTER JOINs.
SELECT strings.*, translations.text
FROM translations INNER JOIN
language ON translations.language_id = language.id RIGHT OUTER JOIN
strings ON translations.string_id = strings.id
WHERE (language.handle = 'english')
I sense it can be achieved with subqueries or by pivoting the tables and performing a LEFT OUTER JOIN but my attempts have failed; my SQL's not what it used to be.
Here's a query builder outline showing the applicable schema: http://dl.getdropbox.com/u/264612/sql-refactor.PNG
First to crack it gets an e-hug from dekz
The following is untested.
select strings.*, translations.text
from strings left outer join translations
on translations.string_id = strings.id
and translations.language_id = (select id
from language
where language.handle = 'english')
I think this will give you all strings with the matching translation text where a suitable translation exists in English. Is that what you are trying to get?
Intriguing that SQLite allows LEFT OUTER JOINs but not RIGHT OUTER JOINs. Well, since it does allow LEFT OUTER JOINs, you're right, you can just rearrange the join order:
SELECT strings.*, translations.text
FROM strings LEFT OUTER JOIN (
translations INNER JOIN language ON translations.language_id = language.id
) tr ON tr.string_id = strings.id
WHERE (language.handle = 'english')
[EDIT: Applied Blorgbeard's suggestion of naming the joined table to get the query to parse -- hope it works now!]