How to construct having clause in Dynamic LINQ - linq-to-sql

I want to find duplicate rows in a table given the list of columns. I am using Dynamic LINQ to group by columns and then want to check if there are any records having count greater than 1.
The group by function and count is working correctly. However, I am not sure how do I construct having clause.
Currently, I am getting list of group count in memory and then identify if there is any duplicate.
var columns = "new(FirstName, LastName)"
dynamic groups = await _dbContext.Users
.Where(x=>x.ClientID = 1234)
.GroupBy(columns)
.Select("new(Count() AS Count)")
.ToListAsync();
I trying to avoid loading list in memory. The query should return boolean like Any() if count is > 1

I think i got it
var columns = "new(FirstName, LastName)"
var found = _dbContext.Users
.Where(x=>x.ClientID = 1234)
.GroupBy(columns)
.Select("new(Count() AS Count)").Where("Count > 1").Any();

Related

Select a random row with where statement is taking to long

I want to select a random row with a specific where statement but the query is taking to long (around 2.7 seconds)
SELECT * FROM PIN WHERE available = '1' ORDER BY RAND() LIMIT 1
The database contains around 900k rows
Thanks
SELECT * FROM PIN WHERE available = '1' ORDER BY RAND() LIMIT 1
means, that you are going to generate a random number for EVERY row, then sort the whole result-set and finally retrieve one row.
That's a lot of work for querying a single row.
Assuming you have id's without gaps - or only little of them - you better use the programming language you are using to generate ONE random number - and fetch that id:
Pseudo-Example:
result = null;
min_id = queryMinId();
max_id = queryMaxId();
while (result == null){
random_number = random_beetween(min_id, max_id);
result = queryById(randomNumber);
}
If you have a lot of gaps, you could retrieve the whole id-set, and then pick ONE random number from that result prior:
id_set = queryAllIds();
random_number = random_beetween(0, size(id_set)-1);
result = queryById(id_set[random_number])
The first example will work without additional constraints. In your case, you should use option 2. This ensures, that all IDs with available=1 are pre-selected into an 0 to count() -1 array, hence ignoring all invalid ids.
Then you can generate a random number between 0 and count() -1 to get an index within that result-set, which you can translate to an actual ID, which you are going to fetch finally.
id_set = queryAllIdsWithAvailableEqualsOne(); //"Condition"
random_number = random_beetween(0, size(id_set)-1);
result = queryById(id_set[random_number])

Facing issue with SQL query in the where clause

I have the following database scheme on MySQL and I would like to retrieve all elements for a speciic id.
So for instance, I would like to retrieve cities, categories, departments linked to the coupon_id=1 (and other fields).
I wrote the following SQL query but unfortunatelly could not get the desired result.
SELECT cc_coupon.id_coupon as idCoupon,
cc_coupon.condition_coupon,
cc_coupon.description,
cc_coupon.type_coupon,
cc_coupon_by_categorie.id_categorie,
cc_categorie.categorie as category,
cc_annonceur.raison_sociale,
cc_coupon_active_in_cities.id_ville as ville_slug,
cc_villes_france.ville_slug,
cc_villes_france.ville_nom_departement,
cc_villes_france.ville_departement
FROM cc_coupon,
cc_coupon_by_categorie,
cc_categorie,
cc_annonceur,
cc_coupon_active_in_cities,
cc_coupon_active_in_departments,
cc_villes_france
WHERE cc_coupon.id_coupon = cc_coupon_by_categorie.id_coupon
and cc_categorie.id_categorie = cc_coupon_by_categorie.id_categorie
and cc_coupon.id_annonceur = cc_annonceur.id_annonceur
and cc_coupon.id_coupon = cc_coupon_active_in_cities.id_coupon
and cc_villes_france.id_ville = cc_coupon_active_in_cities.id_ville
and cc_villes_france.ville_departement = cc_coupon_active_in_departments.ville_departement
and cc_coupon.id_coupon = 1
and cc_coupon_active_in_cities.id_coupon = 1
and cc_coupon_active_in_departments.id_coupon = 1
Thanks for your help.
I think you should use the on and not where when you want to join two tables. When you want to specify other conditions use where clause.

MySQL update with two subqueries

I'm trying to update one column of MySQL table with subquery that returns a date, and another subquery for the WHERE clause.
Here is it:
UPDATE wtk_recur_subs_temp
SET wtk_recur_date = (SELECT final_bb.date
FROM final_bb, wtk_recur_subs
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn)
WHERE wtk_recur_subs_temp.wtk_recur_msisdn IN (select final_bb.msisdn
from final_bb)
The response from the MySQL engine is "Subquery returns more than 1 row".
Use:
UPDATE wtk_recur_subs_temp,
final_bb,
wtk_recur_subs
SET wtk_recur_subs_temp.wtk_recur_date = final_bb.date
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn
AND wtk_recur_subs_temp.wtk_recur_msisdn = final_bb.msisdn
The error is because:
SET wtk_recur_date = (SELECT final_bb.date
FROM final_bb, wtk_recur_subs
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn)
...the final_bb.date value is all the date values where the final_bb and wtk_recur_subs msisdn column values match.
This may come as an utter shock to you, but one of your subqueries is returning more than one row!
This isn't permitted in the circumstance you've set up. Each of those two subqueries must return one and only one row. Or no rows.
Perform each subquery on it's own and determine which one is returning more than one row. If they shouldn't return more than one row, your data may be wrong. If they should return more than one row, you'll either want to modify the data so they don't (as I assume you expect), or add a LIMIT clause. Or add an aggregate function (like MAX) outside the query to do something proper with the multiple rows being returned.

Linq Group on a multi-level object with select statement

I've got 3 dataset objects that are nested with each other using entity set objects. I am selecting the data like this
var newList = from s in MainTable
from a in s.SubTable1 where a.ColumnX = "value"
from b in a.Detail where b.Name = "searchValue"
select new {
ID = s.ID,
Company = a.CompanyName,
Name = b.Name,
Date = s.DueDate
Colour = b.Colour,
Town = a.Town
};
and this works fine, but the trouble is there are many records in the Detail object-list/table for each Name value so I get a load of duplicate rows and thus I only want to display one record per b.Name. I have tried putting
group s by b.Name into g
before the select, but then this seems to stop the select enabling me to select the columns I want (there are more, in practice). How do I use the group command in this circumstance while still keeping the output rows in a "flat" format?
Appending comment as answer to close question:-
Of course that if you group your results, you cant get select a column of a child, thats because there may be more than one childs and you have to specify an aggregate column for example the sum,max etx –

Get the total number of records when doing pagination

To get a page from a database I have to execute something like this:
var cs = ( from x in base.EntityDataContext.Corporates
select x ).Skip( 10 ).Take( 10 );
This will skip the first 10 rows and will select the next 10.
How can I know how many rows would result because of the query without pagination? I do not want to run another query to get the count.
To get the total number of records before skip/take you have to run a separate query. Getting the actual number returned would use Count(), but wouldn't result in another query if the original query was materialized.
var q = from x in base.EntityDataContext.Corporates
select x;
var total = q.Count();
var cs = q.Skip(10).Take(10);
var numberOnSelectedPage = cs.Count();
Bottom line: you have to run two queries. You simply can't get around it.
Here's a good way to do it, however, that caches the original LINQ query and filter, making for less copy/paste errors:
var qry = from x in base.EntityDataContext.Coporates select x;
var count = qry.Count();
var items = qry.Skip(10).Take(10).ToList();