Update table value based on presence in multiple possible arrays (SQL) - sql

I have a members table with regions values in it. This table is first populated at sign up.
The states are sorted into an array for each region:
$region[1] = array("FL","GA","NC","SC","USVI","PR");
$region[2] = array("DC","KY","MD","OH","VA","WV");
$region[3] = array("DE","NJ","NY","PA");
$region[4] = array("CT","MA","ME","NH","RI","VT");
$region[5] = array("IA","IL","IN","MO","MI");
$region[6] = array("AL","AR","LA","MS","TN");
$region[7] = array("AZ","NM","OK","TX");
$region[8] = array("CO","KS","MN","MT","NE","ND","SD","UT","WI","WY");
I then do a recursive search to populate the table based on the region for that state.
$member_region = (recur_search($_SESSION['session_table_membersignup_mailing_state'], $region)) ? recur_search($_SESSION['session_table_membersignup_mailing_state'], $region) : 9;
I added additional regions, so that when new users sign up it will sort them based on the new arrays:
$region[1] = array("FL","GA","NC","SC","USVI","PR");
$region[2] = array("DC","KY","MD","OH","VA","WV");
$region[3] = array("DE","NJ","NY","PA");
$region[4] = array("CT","MA","ME","NH","RI","VT");
$region[5] = array("IA","IL","IN","MO","MI");
$region[6] = array("AL","AR","LA","MS","TN");
$region[7] = array("AZ","NM","OK","TX");
$region[8] = array("ND","NE","MI","MN","SD","WI");
$region[9] = array("AK","CA","NV","OR","WA","HI");
$region[10] = array("CO","ID","MT","UT","WY");
I'm running into issues on how to retroactively update the sql table for existing members using the new arrays.
Bsically: I need to loop through the Members table and update the regions value based on the mailing_state prescence in the new arrays.
I'm struggling with writing a working sql statement to do this. I figured since this is a one time update, I could just run it directly from the database.

Related

Find matching rows in database table using SQL where no matching key is present

I have an old table with legacy data and approx 10,000 rows and a new table with about 500 rows. The columns are the same in both tables. I need to compare a few columns in the new table with the old one and report on data that is duplicated in the new table.
I've researched articles with similar issues, attempted table joins and where exists / where not exists clauses but I just can't get the SQL right. I have included my latest version.
One issue causing trouble for me, I think, is that there is no "Key" as such like a userid or similar unique identifier in either table.
What I want to do is find the data in the "new" table where all rows except for the "reference_number" (doesn't matter if it does or does not) is duplicated, i.e. exists already in the "old" table.
I have this so far...
select
old.reference_number
new.reference_number
new.component
new.privileges
new.protocol
new.authority
new.score
new.means
new.difficulty
new.hierarchy
new.interaction
new.scope
new.conf
new.integrity
new.availability
new.version
from old, new
where
old.component = new.component
old.privileges = new.privileges
old.protocol = new.protocol
old.authority = new.authority
old.score = new.score
old.means = new.means
old.difficulty = new.difficulty
old.hierarchy = new.hierarchy
old.interaction = new.interaction
old.scope = new.scope
old.conf = new.conf
old.integrity = new.integrity
old.availability = new.availability
old.version = new.version
I have tried this here but it doesn't seem to pull out ALL of the data for some reason.
It is evident that actually there are MORE rows in the old table that are duplicated in the new table but I'm only getting a small number of rows returned from the query.
Can anyone spot why that might be, is there another way I should be approaching this?
If it matters, this is Postgresql.
Thanks for any help given.
The following should do what you want:
select distinct o.reference_number,
n.reference_number,
n.component,
n.privileges,
n.protocol,
n.authority,
n.score,
n.means,
n.difficulty,
n.hierarchy,
n.interaction,
n.scope,
n.conf,
n.integrity,
n.availability,
n.version
from new n
inner join old o
on o.component = n.component and
o.privileges = n.privileges and
o.protocol = n.protocol and
o.authority = n.authority and
o.score = n.score and
o.means = n.means and
o.difficulty = n.difficulty and
o.hierarchy = n.hierarchy and
o.interaction = n.interaction and
o.scope = n.scope and
o.conf = n.conf and
o.integrity = n.integrity and
o.availability = n.availability and
o.version = n.version
You should use left join and then select only rows with new values is null. sql should be something like this:
select
old.reference_number
new.reference_number
new.component
new.privileges
new.protocol
new.authority
new.score
new.means
new.difficulty
new.hierarchy
new.interaction
new.scope
new.conf
new.integrity
new.availability
new.version
from old
left join new
on
old.component = new.component
old.privileges = new.privileges
old.protocol = new.protocol
old.authority = new.authority
old.score = new.score
old.means = new.means
old.difficulty = new.difficulty
old.hierarchy = new.hierarchy
old.interaction = new.interaction
old.scope = new.scope
old.conf = new.conf
old.integrity = new.integrity
old.availability = new.availability
old.version = new.version
where new.component is null

sql - selecting, counting and Updating

I'm wondering if this is correct...
I want to select all users from teams in a match and then add a win, loose or draw to his profile.
$short = $_POST['short'];
$opponent = $_POST['opponent'];
$oppuser = safe_query("SELECT userID FROM ".PREFIX."teams_members WHERE teamID='".$opponent."'");
$shortuser = safe_query("SELECT userID FROM ".PREFIX."teams_members WHERE teamID='".$short."'");
safe_query("UPDATE ".PREFIX."teams_members SET win=win+1 WHERE userID='".$oppuser."'");
safe_query("UPDATE ".PREFIX."teams_members SET lost=lost+1 WHERE userID='".$shortuser."'");
Something is not allowing updating the rows.
You don't need those selects. Your update is not working because the select statement is returning you multiple entries. You can update the entire team without selecting the users:
$short = $_POST['short'];
$opponent = $_POST['opponent'];
safe_query("UPDATE ".PREFIX."teams_members SET win=win+1 WHERE teamID='$opponent'");
safe_query("UPDATE ".PREFIX."teams_members SET lost=lost+1 WHERE teamID='$short'");

Postgres no results from linked tables where linked values are null

I have this query:
update CA_San_Francisco as p
set geo = u.geo
from parcels_union u
where u.street_number = p.street_number
and u.street_name = p.street_name
and u.street_type = p.street_type
and u.street_direction = p.street_direction
and u.street_unit = p.street_unit
However it does not update any rows where both fields are null. In other words, if there is no value in street_direction for both tables, I get no result even though they are both the same - both null values.
I get that something can't be = Null. So how do I get all of the results?
Thanks, Brad
You could check if the field is NULL and if it is then change it to something you can check for.
For instance, you can change your Where clause to the following
where coalesce(u.street_number,'') = coalesce(p.street_number,'')
and coalesce(u.street_name,'') = coalesce(p.street_name,'')
and coalesce(u.street_type,'') = coalesce(p.street_type,'')
and coalesce(u.street_direction,'') = coalesce(p.street_direction,'')
and coalesce(u.street_unit,'') = coalesce(p.street_unit,'')
But if there are multiple rows that have NULL in these columns then you will get unexpected assignments in your update...

Query with multiple EXISTS returing too many rows

Original table has 1466303 records in it, I have inserted 1108441 of those records in to a separate table. What I would like to know is what data is left over? So I have made a query using multiple exists to find the data that was left:
SELECT SG_customer,
PHONE,
SG_Name,
SG_Secondary_Address,
SG_Primary_Address,
SG_City,
SG_State,
SG_Zip,
SG_Email
FROM FMJ_DB_VPI_EXPANDED_DATA X
WHERE NOT EXISTS (SELECT 1
FROM FMJScore
WHERE SGID = X.SG_Customer
AND Phone = X.Phone
AND Name = X.SG_Name
AND SecondAddress = X.SG_Secondary_Address
AND Address = X.SG_Primary_Address
AND City = X.SG_City
AND State = X.SG_State
AND Zip = X.SG_Zip
AND Email = X.SG_Email)
Running this returns back 144391 records, there should be a difference of 357862, I don't understand why its returning back so many records.
I assume you want null to be treated equal to null, I also assume that '' is not used as a value, if it is replace it with something that does not normally occur:
SELECT SG_customer,
PHONE,
SG_Name,
SG_Secondary_Address,
SG_Primary_Address,
SG_City,
SG_State,
SG_Zip,
SG_Email
FROM FMJ_DB_VPI_EXPANDED_DATA X
WHERE NOT EXISTS (SELECT 1
FROM FMJScore
WHERE coalesce(SGID,'') = coalesce(X.SG_Customer,'')
AND coalesce(Phone,'') = coalesce(X.Phone,'')
AND coalesce(Name,'') = coalesce(X.SG_Name,'')
AND coalesce(SecondAddress,'') = coalesce(X.SG_Secondary_Address,'')
AND coalesce(Address,'') = coalesce(X.SG_Primary_Address,'')
AND coalesce(City,'') = coalesce(X.SG_City,'')
AND coalesce(State,'') = coalesce(X.SG_State,'')
AND coalesce(Zip,'') = coalesce(X.SG_Zip,'')
AND coalesce(Email,'') = coalesce(X.SG_Email,''))
The optimizer might not be able to use indexes efficiently due to the function call

Creating filter with SQL queries

I am trying to create a filter with SQL queries but am having trouble with numeric values linking to other tables.
Every time I try to link to another table, it takes the same record and repeats it for every element in the other table.
For example, here is query:
SELECT ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID AND
ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0
The last line is the actual filtering criteria.
Here is an example result:
There should only be ONE result (Item has an RID of 0). But it's repeating a copy of the one record for every result inside the substitution groups table (there's 4).
Here is my database schema for reference. The lines indicate relationships between tables and the circles indicate the values I want:
You're forgot to join between ELEMENTS and SUBSTITUTION_GROUPS in your query.
SELECT
ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM
ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE
ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID
AND ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = SUBSTITUTION_GROUPS.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0