How do I convert this SQL query to LINQ-to-SQL? - sql-server-2005

How do I convert this SQL query to LINQ-to-SQL?:
select
COUNT(ua.UserAlertID) as Alerts,
ph.LastName +' '+ ph.MiddleName as Name,
ph.Email,us.UserSystemID,
ur.UserStatus from PHUser ph
inner join UserSystem us on us.UserID=ph.UserID
inner join UserRole ur on ur.UserID=ph.UserID
inner join Role rr on rr.RoleID=ur.RoleID
inner join UserAlerts ua on ua.SeniorID=ph.UserID
group by ph.LastName,ph.MiddleName,ph.Email,us.UserSystemID,ur.UserStatus
I have converted most of the above query to LINQ but I got stuck to counting the number of values on the ua.UserAlertID column: COUNT(ua.UserAlertID) as Alerts.
How do I convert that to LINQ?
Kindly suggest How to convert COUNT(ua.UserAlertID) as Alerts in Linq??
Thanks

Can I see your converted LinQ?
If your Query is ok, you got a line like
group s by new {ua.UserAlertId,...,...} into temp.
as I remember in select new {} part use
select new
{
Total Alerts = temp.Key.UserAlertdId.Count(), ...,...,...,...
}
can you please try this and notify me?

A number of people can help you with this query. It's pretty straightforward. There is a product (very inexpensive) that can help you with these sorts of things. The product is Linqer (http://www.sqltolinq.com/). This tool will convert most SQL statements to Linq. There is a 30 day trial period and I think the cost is < $40. I have used it many times to get up to speed on converting SQL queries to Linq.
Then I might suggest you get a free product called LinqPad. This will allow you to prototype your Linq queries before pasting them into production code. It is a phenomenal tool.

Related

Rails 5 equivalent for this complex SQL query?

I have a query working the way I want, by executing SQL directly, but am curious (just for my own learning purposes) if this same thing could be done in an ActiveRecord statement?
The part I'm struggling with the most is the COALESCE part of this query, which just makes sure that any NULL values from the LEFT JOIN are counted as zeros instead, to keep the summation in order.
Any ideas? I'm using Postgres.
SELECT Inventories.id, Inventories.name, Inventories.unit_of_measure,
COALESCE(Sum(Stocks.count),0) as totalcount
FROM Inventories
LEFT JOIN Stocks
ON Inventories.id = Stocks.inventory_id
WHERE Inventories.property = 'material' AND Inventories.organization_id = #{current_organization.id}
GROUP BY Inventories.id, Stocks.inventory_id
ORDER BY totalcount ASC
LIMIT(5)")
This is the closest I've gotten for an AR equivalent. When I try to add a sum or something like it, that's when it errors out.
#lowmaterials = current_organization.inventories.materials.left_joins(:stocks).group(:id, :inventory_id).order(count: :asc).limit(5)
You can use ActiveRecord::QueryMethods#select:
your_relation.select("column1, column2, COALESCE(1,2) AS column3").left_joins...

Repeated results from an access query

I am new to Access and acually to db's ,
I'm trying to perform a db for recording the results of a really huge survey. So far everything is ok but now that i am designing the Queries I am getting repeated results and I don't know why.
My SQL Statement is:
SELECT T_VALORACIO.IdValoracio, T_ENQUESTA.Treballador,
T_VALORACIO.IdValPreu
FROM (T_ALSECA INNER JOIN T_VALORACIO ON T_ALSECA.idTipus =
T_VALORACIO.idTipus) INNER JOIN T_ENQUESTA ON T_ALSECA.IdAlseca =
T_ENQUESTA.idAlSeca
WHERE (((T_ENQUESTA.Treballador)=True) AND ((T_VALORACIO.IdValPreu)=4));
I would expect getting the results that fit both cases, but the results that fit just the first case are also shown.
Thanks in advance !
Try using instead:
SELECT DISTINCT
This removes duplicate rows.

Access Sql about pivot

I have four tables now.
StuInfo
ActInfo
ActAttendance
ActLateArriveAndEarlyLeave
For Type, 1 = late arrive, 2 = early leave
Is it possible to generate a query like this with one sql statement?
C3:E4 are the cells which store the total time a person invloved in an activity.
Or if it is not possible, I want to export the final result to an Excel file.
How can I do it in VBA?
Thanks very much. Please let me know if I didn't explain clearly enough.
Pivot table is what you need unfortunately I cannot find a way to export one from Access as a flat query. It will only export it as a pivot table in excel. This query will get you the correct data. Then you have to create a pivot from it
SELECT DISTINCT
StuInfo.StuName AS Name,
StuInfo.Stu_No,
DateDiff("h",IIf([AcctLateAriveAndEarlyLeave].[Type]=1,[AcctLateAriveAndEarlyLeave].[Time],[AcctInfo].[sTime]),IIf([AcctLateAriveAndEarlyLeave].[Type]=2,[AcctLateAriveAndEarlyLeave].[Time],[AcctInfo].[eTime])) AS AttendedFor, Format([AcctInfo].[sTime],"mm/dd/yyyy") AS OnDate
FROM ((StuInfo LEFT JOIN AcctAttendance ON StuInfo.Stu_No = AcctAttendance.Stu_No) LEFT JOIN AcctInfo ON AcctAttendance.[Act_S/N] = AcctInfo.[S/N]) LEFT JOIN AcctLateAriveAndEarlyLeave ON StuInfo.Stu_No = AcctLateAriveAndEarlyLeave.Stu_No;
Then you can create a pivot table that looks like this
Obviously if you want something other than explicit hours you have to change the query a bit.
A crosstab query can work. However, I need a little bit more information for what the values under date fields calculate. In my example I assume they are Max(Type)
TRANSFORM Max(Type) AS MaxOfType
SELECT StuInfo.SteName, StuInfo.Stu_No FROM StuInfo
INNER JOIN ActLateArriveAndEarlyLeave ON StuInfo.Stu_No = ActLateArriveAndEarlyLeave.Stu_No
GROUP BY StuInfo.Ste_No, StuInfo.SteName
PIVOT Format(ActLateArriveAndEarlyLeave.TimeValue, 'short date');

LinqPad - Convert SQL to Linq command

I recently purchased LINQPad in hopes that it would allow me to convert SQL statements into LINQ statements.
Using LINQPad, I am able to attach a DB and run the SQL statement which returns the results I need.
But I can not find a 'command' to convert that SQL statement into LINQ.
Can you please let me know how to convert SQL to LINQ by using LINQPad OR another tool?
There is a tool called Linqer, but be careful: transliterating from SQL to LINQ can give you the worst of both worlds.
For instance, suppose you want all purchases of $1000 or greater paid for in cash or by customers who live in Washington. Here's the query in SQL:
SELECT p.*
FROM Purchase p
LEFT OUTER JOIN
Customer c INNER JOIN Address a ON c.AddressID = a.ID
ON p.CustomerID = c.ID
WHERE
(a.State = 'WA' || p.CustomerID IS NULL)
AND p.ID in
(
SELECT PurchaseID FROM PurchaseItem
GROUP BY PurchaseID HAVING SUM (SaleAmount) > 1000
)
How would translate this to LINQ? The wrong way is to transliterate the query into LINQ, trying to reproduce the outer and inner joins, subquery and group clause. The right way is to map your original query (in English) directly into LINQ, leveraging LINQ's linear flow of data and association properties:
I want all purchases...
from p in db.Purchases
...of $1000 or greater...
where p.PurchaseItems.Sum (pi => pi.SaleAmount) > 1000
...paid for in cash...
where p.Customer == null
...or by customers who live in Washington
|| p.Customer.Address.State == "WA"
Here's the final query:
from p in db.Purchases
where p.PurchaseItems.Sum (pi => pi.SaleAmount) > 1000
where p.Customer == null || p.Customer.Address.State == "WA"
select p
More info here.
In general there are no tools to covert SQL to Linq as #andres-abel mention before, but sometimes you have to write Linq that will execute exactly as specified SQL (for example because of performance issues, backward compatability or some other reasons).
In this case I'll advice you to do reverse engineering by yourself:
configure logging of dump SQL statements generated by Linq to stdout using
ObjectQuery.ToTraceString,
DbCommand.CommandText,
logger availabe to your data source
manually rewrite Linq statement until you'll get what you need
LinqPad contains no SQL->LINQ translator. LinqPad does actually not contain any LINQ->SQL translator either. It relies on the .Net Linq-to-Sql library or Entity framework for the translation.
I don't know of any other tool with that capability either. In simple cases it would be possible to make one, but for more complex scenarios it would be impossible as there is no LINQ expression that matches some SQL constructs.

Slow Query - Help with Optimization

Hey guys. This is a follow-on from this question:
After getting the right data and making some tweaks based on requests from business, I've now got this mini-beast on my hands. This query should return the total number of new jobseeker registrations and the number of new uploaded CV's:
SELECT COUNT(j.jobseeker_id) as new_registrations,
(
SELECT
COUNT(c.cv_id)
FROM
tb_cv as c, tb_jobseeker, tb_industry
WHERE
UNIX_TIMESTAMP(c.created_at) >= '1241125200'
AND
UNIX_TIMESTAMP(c.created_at) <= '1243717200'
AND
tb_jobseeker.industry_id = tb_industry.industry_id
)
AS uploaded_cvs
FROM
tb_jobseeker as j, tb_industry as i
WHERE
j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND
i.industry_id = j.industry_id
GROUP BY i.description, MONTH(j.created_at)
Notes:
- The two values in the UNIX TIMESTAMP functions are passed in as parameters from the report module in our backend.
Every time I run it, MySQL chokes and lingers silently into the ether of the Interweb.
Help is appreciated.
Update: Hey guys. Thanks a lot for all the thoughtful and helpful comments. I'm only 2 weeks into my role here, so I'm still learning the schema. So, this query is somewhere between a thumbsuck and an educated guess. Will start to answer all your questions now.
tb_cv is not connected to the other tables in the sub-query. I guess this is the root cause for the slow query. It causes generation of a Cartesian product, yielding a lot more rows than you probably need.
Other than that I'd say you need indexes on tb_jobseeker.created_at, tb_cv.created_at and tb_industry.industry_id, and you might want to get rid of the UNIX_TIMESTAMP() calls in the sub-query since they prevent use of an index. Use BETWEEN and the actual field values instead.
Here is my attempt at understanding your query and writing a better version. I guess you want to get the count of new jobseeker registrations and new uploaded CVs per month per industry:
SELECT
i.industry_id,
i.description,
MONTH(j.created_at) AS month_created,
YEAR(j.created_at) AS year_created,
COUNT(DISTINCT j.jobseeker_id) AS new_registrations,
COUNT(cv.cv_id) AS uploaded_cvs
FROM
tb_cv AS cv
INNER JOIN tb_jobseeker AS j ON j.jobseeker_id = cv.jobseeker_id
INNER JOIN tb_industry AS i ON i.industry_id = j.industry_id
WHERE
j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND cv.created_at BETWEEN '2009-05-01' AND '2009-05-31'
GROUP BY
i.industry_id,
i.description,
MONTH(j.created_at),
YEAR(j.created_at)
A few things I noticed while writing the query:
you GROUP BY values you don't output in the end. Why? (I've added the grouped field to the output list.)
you JOIN three tables in the sub-query while only ever using values from one of them. Why? I don't see what it would be good for, other than filtering out CV records that don't have a jobseeker or an industry attached — which I find hard to imagine. (I've removed the entire sub-query and used a simple COUNT instead.)
Your sub-query returns the same value every time. Did you maybe mean to correlate it in some way, to the industry maybe?.
The sub-query runs once for every record in a grouped query without being wrapped in an aggregate function.
First and foremost it may be worth moving the 'UNIX_TIMESTAMP' conversions to the other side of the equation (that is, perform a reverse function on the literal timestamp values at the other side of the >= and <=). That'll avoid the inner query having to perform the conversions for every record, rather than once for the query.
Also, why does the uploaded_cvs query not have any where clause linking it to the outer query? Am I missing something here?