using WHERE with SET in an UPDATE - mysql

I am new user with MySQL 5.6 and trying to UPDATE a table using NAVICAT
I trying to condition the SET statement with a WHERE. It seems I have taken the wrong approach. Can someone point me in the right direction?
UPDATE vacation_watch
INNER JOIN property_names
ON vacation_watch.Mstrfromproperty = property_names.MstrLink
INNER JOIN property_names_subnames
ON property_names_subnames.NameLink = property_names.NameLink
SET vacation_watch.Watch_Requester_Last = property_names.Name_Last,
vacation_watch.Watch_Requester_First = property_names.Name_First,
vacation_watch.Watch_Requester_Phone = property_names.Name_Phone,
vacation_watch.Emergency_Contact_Name = property_names_subnames.Sub_Name_Last WHERE property_names_subnames.Sub_Name_Type = "KEYHOLDER"
vacation_watch.Emergency_Contact_Phone = property_names_subnames.Sub_Name_Phone WHERE property_names_subnames.Sub_Name_Type = "EMERGENCY"

You are using two WHERE clauses and in the wrong way.
What you are looking for is actual conditional SQL. There is already an answer on SO that could help you achieving what you want to do here.
Furthermore, there can only be only one WHERE clause that applies on the global level, not at field level.
Something like:
UPDATE vacation_watch
INNER JOIN property_names
ON vacation_watch.Mstrfromproperty = property_names.MstrLink
INNER JOIN property_names_subnames
ON property_names_subnames.NameLink = property_names.NameLink
SET vacation_watch.Watch_Requester_Last = property_names.Name_Last,
vacation_watch.Watch_Requester_First = property_names.Name_First,
vacation_watch.Watch_Requester_Phone = property_names.Name_Phone,
vacation_watch.Emergency_Contact_Name =
CASE WHEN property_names_subnames.Sub_Name_Type = "KEYHOLDER"
THEN property_names_subnames.Sub_Name_Last
END
vacation_watch.Emergency_Contact_Phone =
CASE WHEN property_names_subnames.Sub_Name_Type = "EMERGENCY"
THEN property_names_subnames.Sub_Name_Phone
END
could work. I hope I got what you wanted to do correctly and my syntax is correct as I just wrote it in a text editor and didn't test it.

Related

Linq Join vs .Where().DefaultIfEmpty()

Getting to grips with Linq and I have a query that contains alot of joins to other tables.
I won't put the whole query here as it's not really relevant to my actual question.
I'm wondering which is the better way to write my query and why?
Query 1 :
var query = from team in context.tblTeams
join manager in context.tblManagers on team.fkManager equals manager.pkManager into managerJoin
from manager in managerJoin.DefaultIfEmpty()
join colour in context.tblTeamColours on team.fkTeamColour equals colour.pkTeamColour into colourJoin
from colour in colourJoin.DefaultIfEmpty()
join sponser in context.tblSponsers on team.fkSponser equals sponser.pkSponser into sponserJoin
from sponser in sponserJoin.DefaultIfEmpty()
select new TeamView
{
pkTeam = team.pkTeam,
strManager = manager.strManagerName,
strTeamColour = colour.strColour,
strSponser = sponser.strSponser
};
Query 2:
var query = from team in context.tblTeams
from manager in context.tblManagers.Where(x => x.pkManager == team.fkManager).DefaultIfEmpty()
from colour in context.tblTeamColours.Where(x => x.pkTeamColour == team.fkTeamColour).DefaultIfEmpty()
from sponser in context.tblSponsers.Where(x => x.pkSponser == team.fkSponser).DefaultIfEmpty()
select new TeamView
{
pkTeam = team.pkTeam,
strManager = manager.strManagerName,
strTeamColour = colour.strColour,
strSponser = sponser.strSponser
};
They both seem to take pretty much the same amount of time to run. I'm just wondering if there is any difference other than readability?
With 33 joins in the full query the second method seems neater and easier to read to me.
Alternatively, how else can I write the query which could make it faster?

Django: ORM/SQL query speed significantly decreased after adding additional BooleanField or (SQL tinyint) to Django Filter

Using MySQL Latest Django:
I have a vaguely complex Django query that works quite quickly--until I add an additional "AND" with a Boolean Field--
See Below:
queriedForms = queryFormtype.form_set.filter(is_public=True)
newQuery = queriedForms.filter(formrecordattributevalue__record_value__icontains=term['TVAL'], formrecordattributevalue__record_attribute_type__pk=rtypePK)
newQuery = newQuery.filter(flagged_for_deletion=False)
logger.info(newQuery.query)
term['count'] = newQuery.count()
If I either remove the initial "is_public=True" or the final "flagged_for_deletion=False)--it works incredibly fast. If I use both as filters, it increases the time for the count() function by something like 2000%
The different QuerySet.query outputs are below:
SELECT `maqluengine_form`.`id`, `maqluengine_form`.`form_name`, `maqluengine_form`.`form_number`, `maqluengine_form`.`form_geojson_string`, `maqluengine_form`.`hierarchy_parent_id`, `maqluengine_form`.`is_public`, `maqluengine_form`.`project_id`, `maqluengine_form`.`date_created`, `maqluengine_form`.`created_by_id`, `maqluengine_form`.`date_last_modified`, `maqluengine_form`.`modified_by_id`, `maqluengine_form`.`sort_index`, `maqluengine_form`.`form_type_id`, `maqluengine_form`.`flagged_for_deletion` FROM `maqluengine_form` INNER JOIN `maqluengine_formrecordattributevalue` ON (`maqluengine_form`.`id` = `maqluengine_formrecordattributevalue`.`form_parent_id`) WHERE (`maqluengine_form`.`form_type_id` = 319 AND `maqluengine_form`.`is_public` = True AND `maqluengine_formrecordattributevalue`.`record_value` LIKE %seal% AND `maqluengine_formrecordattributevalue`.`record_attribute_type_id` = 18510 AND `maqluengine_form`.`flagged_for_deletion` = False)
SELECT `maqluengine_form`.`id`, `maqluengine_form`.`form_name`, `maqluengine_form`.`form_number`, `maqluengine_form`.`form_geojson_string`, `maqluengine_form`.`hierarchy_parent_id`, `maqluengine_form`.`is_public`, `maqluengine_form`.`project_id`, `maqluengine_form`.`date_created`, `maqluengine_form`.`created_by_id`, `maqluengine_form`.`date_last_modified`, `maqluengine_form`.`modified_by_id`, `maqluengine_form`.`sort_index`, `maqluengine_form`.`form_type_id`, `maqluengine_form`.`flagged_for_deletion` FROM `maqluengine_form` INNER JOIN `maqluengine_formrecordattributevalue` ON (`maqluengine_form`.`id` = `maqluengine_formrecordattributevalue`.`form_parent_id`) WHERE (`maqluengine_form`.`form_type_id` = 319 AND `maqluengine_form`.`is_public` = True AND `maqluengine_formrecordattributevalue`.`record_value` LIKE %seal% AND `maqluengine_formrecordattributevalue`.`record_attribute_type_id` = 18510)
The first takes about 20/30 seconds to perform the count(), while the second with only 1 of the two BooleanField's takes less than a second to perform the count()
=======================================
EDIT=======================
Apologies: since the question isn't obvious enough--why is adding an additional AND with a BooleanField increasing the query time by +2000%? Is anyone able to assist in figuring out WHY that's occurring. Thanks.
EDIT=========================
Also discovered that using a exclude(is_public=False) rather than filter(is_public=True) has the same effect as the solution below. Does anyone happen to know why an exclude() works fine--whereas the filter() does not?
==============================
Solution I came up with after a night's rest:
--I keep the query as is(I need it for later because it continues getting chain filtered)
--I need the count() from this stage--which is taking substantially longer than it should with the additional BooleanField AND
--I take a temporary values list to perform a len() on instead:
queriedForms = queryFormtype.form_set.all()
newQuery = queriedForms.filter(formrecordattributevalue__record_value__icontains=term['TVAL'], formrecordattributevalue__record_attribute_type__pk=rtypePK)
newQuery = newQuery.filter(flagged_for_deletion=False)
tempQuery = newQuery.values_list('is_public',flat=True)
finalQuery = [entry for entry in tempQuery if entry != 'False'] #Remove any indices that contain "False"
term['count'] = len(finalQuery)
The following counts that use chained filters after use the same technique--it's significantly faster--if not as fast as removing one of the Booleans from the filters.

Access UPDATE statement in query fails to actually update

The following tables exist:
Passerine_Survey_Observation
Species_Codes
I'm trying to set the common name in Passerine_Survey_Observation with that of Species_Codes:
UPDATE Passerine_Survey_Observation
INNER JOIN Species_Codes ON Passerine_Survey_Observation.SPEC_FK = Species_Codes.SPEC
SET Passerine_Survey_Observation.Species_Common_Name = Species_Codes.COMMONNAME;
It says an update will occur; however, nothing changes in Passerine_Survey_Observation.
Supposed update warning
If I do this an update does occur as expected:
SET Passerine_Survey_Observation.Species_Common_Name = 'test'
#Knox was onto something...
This behavior occurred because the target field (Passerine_Survey_Observation.Species_Common_Name) - in Design View - was a List Box (under the Properties > Lookup tab). Setting that to Display Control = Text Box resolved the problem. Oops.
Final code:
UPDATE Passerine_Survey_Observation
INNER JOIN Species_Codes ON Passerine_Survey_Observation.[SPEC_FK] = Species_Codes.[SPEC]
SET Passerine_Survey_Observation.Species_Common_Name = Species_Codes.[COMMONNAME]
WHERE Passerine_Survey_Observation.Species_Common_Name IS NULL;

Django ORM query field weight?

I'm doing the following query:
People.objects.filter(
Q(name__icontains='carolina'),
Q(state__icontains='carolina'),
Q(address__icontains='carolina'),
)[:9]
I want the first results of the query to be the people who is named "Carolina" (and also matches other fields, but name first). The problem is that I don't think is any way to determine a field "weight" or "priority".
Any idea?
Thanks!
You'll need to do 3 queries for this to work:
names_match = People.objects.filter(name__icontains='carolina')[:9]
states_match = People.objects.filter(state__icontains='carolina')[:9]
addresses_match = People.objects.filter(address__icontains='carolina')[:9]
all_objects = list(names_match) + list(states_match) + list(addresses_match)
all_objects = all_objects[:9]
There are two problems with this approach, which are fairly easily worked round:
It does unnecessary queries (what if names_match contained enough items already).
It allows for duplicates (what if someone in North Carolina is called Carolina?)
This should work:
qs = People.objects.filter(name__icontains='carolina') | People.objects.filter( Q(state__icontains = 'carolina'), Q(address__icontains='carolina')).distinct()
qs = list(qs)[:9]
Or if you want a pure duplicate free list:
qs = list(set(qs))[:9] #for a duplicate free list

Correlate 2 columns in SQL

SELECT ica.CORP_ID, ica.CORP_IDB, ica.ITEM_ID, ica.ITEM_IDB,
ica.EXP_ACCT_NO, ica.SUB_ACCT_NO, ica.PAT_CHRG_NO, ica.PAT_CHRG_PRICE,
ica.TAX_JUR_ID, ica.TAX_JUR_IDB, ITEM_PROFILE.COMDTY_NAME
FROM ITEM_CORP_ACCT ica
,ITEM_PROFILE
WHERE (ica.CORP_ID = 1000)
AND (ica.CORP_IDB = 4051)
AND (ica.ITEM_ID = 1000)
AND (ica.ITEM_IDB = 4051)
AND ica.EXP_ACCT_NO = ITEM_PROFILE.EXP_ACCT_NO
I'm trying basically say since the exp account code is '801500' then the Name should return "Miscellaneous Medic...".
It seems as if what you are showing is not possible. Have you edited the data in the editor??? You are joining using ica.EXP_ACCT_NO = ITEM_PROFILE.EXP_ACCT_NO . Therefore, every entry with EXP_ACCT_NO = 801500, should also have the same COMDTY_NAME.
However, it could be the case that your IDs are not actually numbers and that they are strings with whitespace (801500__ vs 801500 ). But since you are not performing a left-outer join, it would also mean you have an entry in ITEM_PROFILE with the same whitespace.
You also need to properly normalize your table data (unless this is a view) but it still means you have erroneous data.
Try to perform the same query, but using the TRIM function to remove whitespace: https://stackoverflow.com/a/6858168/1688441 .
Example:
SELECT ica.CORP_ID, ica.CORP_IDB, ica.ITEM_ID, ica.ITEM_IDB,
ica.EXP_ACCT_NO, ica.SUB_ACCT_NO, ica.PAT_CHRG_NO, ica.PAT_CHRG_PRICE,
ica.TAX_JUR_ID, ica.TAX_JUR_IDB, ITEM_PROFILE.COMDTY_NAME
FROM ITEM_CORP_ACCT ica
,ITEM_PROFILE
WHERE (ica.CORP_ID = 1000)
AND (ica.CORP_IDB = 4051)
AND (ica.ITEM_ID = 1000)
AND (ica.ITEM_IDB = 4051)
AND trim(ica.EXP_ACCT_NO) = trim(ITEM_PROFILE.EXP_ACCT_NO);