MySQL - Updating a table from another table - c#

I am writing a small app (c#/WPF/MySQL). One of things that I want to do is to update some product descriptions within a table.
Here is a slightly altered version of the query that I thought could be the starting point:
SELECT
`egx_machine`.`contact_id` AS `contact_id`,
`egx_machine`.`gtr2_product_family` AS `gtr2_product_family`,
`egx_machine`.`gtr2_product_family_factory` AS `gtr2_product_family_factory`,
`egx_machine`.`gtr2_product_family_model` AS `gtr2_product_family_model`,
`egx_machine`.`gtr2_product_family_size` AS `gtr2_product_family_size`,
`egx_machine_extra`.`contact_name` AS `contact_name`,
`gtxuk_r2_machine`.`machine_desc` AS `machine_desc`,
`gtxuk_r2_machine`.`product_family` AS `product_family`,
`gtxuk_r2_machine`.`factory` AS `factory`,
`gtxuk_r2_machine`.`model` AS `model`,
`gtxuk_r2_machine`.`size` AS `size`
FROM (((`egx_machine`
JOIN `egx_machine_extra`
ON ((`egx_machine`.`contact_id` = `egx_machine_extra`.`contact_id`)))
JOIN `gtxuk_machine`
ON ((`egx_machine_extra`.`contact_value` = `gtxuk_machine`.`machine_id`)))
JOIN `gtxuk_r2_machine`
ON ((CONVERT(`gtxuk_machine`.`machine_desc` USING utf8) = `gtxuk_r2_machine`.`machine_desc`)))
WHERE (`egx_machine_extra`.`contact_name` = 'mac_type')
But somehow, I need to turn this into an update query where:
`egx_machine`.`gtr2_product_family` = `gtxuk_r2_machine`.`product_family`
and
`egx_machine`.`gtr2_product_family_factory = `gtxuk_r2_machine`.`factory`
I know it's a bit long winded - but I started off with a full head of hair and now look like kojak.

If you want to update the values in the product table you can do as
update
products p
join products_new_data pn on pn.product_name = p.product_name
set
p.product_name_new = pn.product_name_new ,
p.product_source = pn.product_source ;
For doing it reverse you can do as
update
products_new_data pn
join products p on p.product_name = pn.product_name
set
pn.product_name_new = p.product_name_new,
pn.product_source = p.product_source ;
UPDATE
From the comments I guess this is what you are looking at, however its really hard to write a query without the schema and some data, but I think this should be pretty close what you are looking at if I am not misunderstood your question
update egx_machine em
JOIN egx_machine_extra emx on emx.contact_id = em.contact_id
JOIN gtxuk_machine gm on emx.contact_value = gm.machine_id
JOIN gtxuk_r2_machine g2m on CONVERT(gm.machine_desc USING utf8) = g2m.machine_desc
set
em.gtr2_product_family = g2m.product_family ,
em.gtr2_product_family_factory = g2m.factory

Related

performance difference sql query with LINQ and classic asp

I'm developing an asp.net web forms 4.5 website,
and I've come to a problem where I have to perform an sql query
from sql server originally written by classic asp.
The original query goes like this..
select trait1, trait2, sum(qty) as qty from table2
right outer join table1 on (table1.col == table2.col)
where table2.idx is null
group by trait1, trait2
order by trait1, trait2
and as I'm writing a .net program, I'm trying to rewrite this query...
as something like this
var myHashSet = new HashSet<string>(table2.Select(c => c.col));
from item in table2
where !myHashSet.Contains(item.col)
group item.qty by new {item.trait1, item.trait2} into total
select new
{
trait1 = total.Key.trait1,
trait2 = total.Key.trait2,
qty = total.Sum()
} into anon
order by anon.qty descending
select anon
ps : ignore the order by part.. it's not important
for classic asp, it takes like 1.5 seconds, but for c# asp.net,
it takes roughly 8 seconds.
The queries are not exactly like that but its almost similar to what I wrote.
I cannot figure out why it's taking so long..
Can someone tell me why it's taking so long and how I should fix it?
you don't need the hashset, use a join instead, your query might look like
var inner = from two in table2
join one in table1
on two.col equals one.col
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};
Edit
for completeness i'm adding also a left join variant
var left = from two in table2
from one in
(
from temp in table1
where temp.col == two.col
select temp
).DefaultIfEmpty()
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};

TSQL - Select from table with multiple join paths

That title is not very good, so consider the following. I have five tables:
User {
Id,
ProfileId // -> Profiles.Id
}
Profile {
Id
}
ProfilePermissionSets {
ProfileId // -> Profiles.Id
PermissionSetId // -> PermissionSets.Id
}
UserPermissionSets {
UserId // -> Users.Id
PermissionSetId // -> PermissionSets.Id
}
PermissionSets {
Id
}
Permissions {
Id,
PermissionSetId // -> PermissionSets.Id
}
And I want get all of the permissions for a user that are directly linked to it or indirectly through the profile. The not-quite-there SQL I've come up with so far is this:
SELECT [Pe].[Controller],
[Pe].[Action]
FROM [PermissionSets] AS [PS]
JOIN [UserPermissionSets] AS [UPS]
ON ([UPS].[PermissionSetId] = [PS].[Id])
JOIN [Users] AS [U]
ON ([U].[Id] = [UPS].[UserId])
JOIN [Profiles] AS [P]
ON ([P].[Id] = [U].[ProfileId])
JOIN [ProfilePermissionSets] AS [PPS]
ON ([PPS].[ProfileId] = [P].[Id])
JOIN [Permissions] AS [Pe]
ON ([Pe].[PermissionSetId] = [PS].[Id])
WHERE [U].[Id] = 4;
It returns back a correct count of rows, but it's repeating the controller or action over and over, so it's wrong. I'm hoping someone can help me correct it to show all of the distinct permission sets for the user. Ideally, I'd like to also change it so that it's all discovered starting at the user because that is what I have access to in the method I need to do this (the object is an Entity Framework class named User and will be browsed using LINQ).
UPDATED because I forgot that I really wanted the permissions not the permission sets.
Try this SQL
SELECT [Pe].[Controller],
[Pe].[Action]
FROM [Users] AS [U]
LEFT OUTER JOIN [UserPermissionSets] AS [UPS]
ON ([UPS].[UserId] = [U].[Id])
LEFT OUTER JOIN [ProfilePermissionSets] AS [PPS]
ON ([PPS].[ProfileId] = [U].[ProfileId])
LEFT OUTER JOIN [Permissions] AS [Pe]
ON ([Pe].[PermissionSetId] = [UPS].[PermissionSetId])
OR ([Pe].[PermissionSetId] = [PPS].[PermissionSetId])
WHERE [U].[Id] = 4;
So, messing around on LINQPad, I came up with this as far as the LINQ query:
user.PermissionSets.Union(user.Profile.PermissionSets).SelectMany(
ps =>
ps.Permissions.Select(
p =>
p.Controller + "." + p.Action));
And it produces what I want, BUT it does it by composing the results of a bunch of SQL queries. The biggest impact comes from profiles that have multiple permission sets, like say the Administrator. I don't think there's a way around it, and I only have a User object to work with, so I'm ok with the excess SQL queries, at least for now.

Average numbers in my SQL query

I have a question regarding my SQL query. Below you will see my database:
And I have the following query right now:
SELECT enquete_vraag,enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
And I display the returned data in a datagridview:
Now the datagridview shows all questions that are being answered by all students. What I want is the average for each question and only show that. So you have 1 row that has question 6 with the average answer and question 7 with the average answer and so on, how do I achieve that in my SQL query?
hi you should do something like this
SELECT enquete_vraag,AVG(enquete_antwoord) enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
GROUP BY enquete_vraag, docent,vak,semesterstart
SELECT enquete_vraag,AVG(enquete_antwoord) as [enquete_antwoord]
FROM ...
GROUP BY enquete_vraag
The problem then, of course, becomes which vak etc to choose.... Because of translation, it is not easy for me to guess at which value means what, so it is hard to advise on that. You might be able to include the extra values in the GROUP BY clause (if they are the same for all the matching rows); or you might be able to take a MIN / MAX.
just add avg function in your code.
...AVG(enquete_antwoord)...
write above code it gives you the correct answer

Select all tags that are user in questions asp.net c# EF

There are four tables:
Questions(questionId, question)
QuestionTags(questionTagId, questionId, tagId)
CodingKeys(codingKeyId, codingTypeId ..)
Codings(codingId, codingKeyId, coding ..)
I want to select all question tagIds and their codings (codingKeyId is foreign key of tagId) that are represented in Questions... So if I have 10 different codings in Codings table but only two of them are represented in Questions I want to select only these two.
I tried with join like this:
var query = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
select new
{
tagId = qt.tagId,
coding = c.coding
};
But the above solution gave me double results. For example, if one tag is included in more than one question, I get the same tag twice (I tried distinct, but that didn't work).
I also tried using Any:
var query= context.QuestionTags
.Where(qt => qt.Questions.QuestionTags.Any(q => q.tagId == qt.tagId))
.Select(qt => new
{
codingKeyId = qt.questionId,
coding = context.Codings.FirstOrDefault(c => c.CodingKeys.codingKeyId == qt.tagId).coding
});
The same thing happened here, I got duplicate results, but Distinct didn't work (don't know why).
However, if I use this SQL statement:
SELECT distinct tagId, coding
FROM QuestionTags
LEFT OUTER JOIN Codings ON codingKeyId LIKE QuestionTags.tagId
WHERE Codings.languageId = 1
I get the right result, but I don't want to write and store a procedure for this. I really wan't to know if I can solve this with EF (linq), and I am also not sure if distinct is the right solution.
Thanks for your help.
You can use group by in order to get just the results you want.
var query = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
group qt by new {tagId = qt.tagId,coding = c.coding } into element
select new
{
tagId = element.Key.tagId,
coding = element.Key.coding
};
Please mark it as answer if you find it useful
var result = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
where c.languageId == 1
select new
{
codingKeyId = qt.tagId,
coding = c.coding
};
return result.Distinct()
Ok, like this it is working, but is this the only way to use it with distinct and join... I am not sure if this is the right solution (but it gives me the right result) ... maybe it can be optimized a bit...
Try
var query = from qt in context.Codings
join c in context.QuestionTags on qt.tagId equals c.codingKeyId
select new
{
tagId = qt.tagId,
coding = c.coding
};

NHibernate Criteria engine with inner join and subquery

Is it posible in NHibernate to create a query that looks like this?
select hi.ContactId
From dbo.vw_HostInterests hi INNER JOIN
( Select cm1.ContactId
From dbo.vw_ContactMoments cm1 INNER JOIN
(
Select Contactid
From dbo.vw_ProfileNaw
where GenderId = 1000
) as pn1 on cm1.ContactId = pn1.ContactId
where cm1.ActivityId = 1001
)as cm on hi.ContactId = cm.ContactId
where hi.ActivityId = 1038
I've managed to create the correct output with the IN statement, but I'd realy like the SQL to look like this.
The Criteria below shows part of above query with the IN Statement I used (but want to replace):
ICriteria criteria = DbSession.CreateCriteria<Contact>();
var dCriteria1 = DetachedCriteria.For(typeof(VwHostInterest))
.Add(Expression.Eq("ActivityId", 1038))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
var dCriteria2 = DetachedCriteria.For(typeof(VwContactMoment))
.Add(Expression.Eq("ActivityId", 1001))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria1));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria2));
int count = (Int32)criteria
.SetProjection(Projections.Count("ContactId"))
.UniqueResult();
Probably not the answer you are looking for and apologies if it isn't but my experience is that your best bet with such complex queries would be to:
a) Do this whole thing as a view and map it in NHibernate
b) Create the inner select as a view and create a mapping such that you can relate it in your query
b) Or override nhibernate (override as in skip and not in OO terms ;) and write this as a named query using native SQL.
Does that nested query produce the same result as the following?
SELECT hi.ContactId
FROM dbo.vw_HostInterests hi
INNER JOIN vw_ContactMoments cm1 on hi.ContactId = cm1.ContactId
AND cm1.ActivityId = 1001
INNER JOIN dbo.vw_ProfileNaw pn1 on pn1.ContactId = cm1.ContactId
AND pn1.GenderId = 1000
WHERE hi.ActivityId = 1038

Categories