MySQL Update, Set with Where not working? - mysql

I have read other posts and I really don't understand what I am doing wrong here because it is such a simple statement.
anything in '()' are comments
Query:
[UPDATE users, sites
SET users.idSiteRegUsers='1'
WHERE sites.SiteActivateSites='DEL' ]
(TBL's to select to update within the whole query)
(Setting the users tbl idSiteRegUsers to 1)
(Where only the sites in tbl sites = DEL)
I've also read http://bugs.mysql.com/bug.php?id=52651 and tried changing the INT to VARCHAR and UPDATING 0 to DEL due to the bug but still same result.
Issue:
I have 2129 records that need updating as found using a simple select statement to understand the number of results.
([SELECT
sites.SiteActivateSites,
sites.id_Sites,
users.idSiteRegUsers,
users.CompanyNameUsers,
sites.LinkNameSites
FROM
users
INNER JOIN sites ON users.idSiteRegUsers = sites.id_Sites
WHERE
sites.SiteActivateSites != '1']) 'simple'
But the UPDATE query updates all 4000+ records, not just the records that = DEL but the ones that are reference to another value e.g. = 1.
Have I missed something?
Cheers,
Joe

Just as with your SELECT command, you need to tell MySQL how the tables are joined: your UPDATE is currently doing a full cartesian product of both tables (with every row in users joined with every row in sites - therefore the WHERE condition filtering on sites is still resulting in a match on every record from users).
Try instead:
UPDATE users JOIN sites ON users.idSiteRegUsers = sites.id_Sites
SET users.idSiteRegUsers='1'
WHERE sites.SiteActivateSites='DEL'

Related

mysql inner join not working as expected

Sorry about this. There are a million posts about this. Somehow, I am still missing something. Simple inner join exactly as this:
http://www.w3resource.com/mysql/advance-query-in-mysql/inner-join-with-multiple-tables.php
Clueless what the problem is. Just trying to add the org to the machine record.
I expect that if there is no match on user_name, the machine record will be dropped, or not, but either way, <= number of records in machines. Getting multiples. Machines.machine_name and user_name are not unique in machines as each machine has multiple software packages tracked.
select users2.org, machines.User_name, machines.Machine_name, machines.model, machines.program, machines.version
from machines inner join users2 on users2.user_name = machines.User_name
You probably want to aggregate here because you will get a cartesian product for all of the machines that share a user_name:
select users2.org,
machines.User_name,
machines.Machine_name,
machines.model
from machines
inner join users2 on users2.user_name = machines.User_name
GROUP BY users2.org, machines.User_name, machines.Machine_name, machines.model
Thank you for your input. The issue was that somehow when the data was massaged (user_name was originally email in 1 case and windows network id in the other), the missing user_names in both tables got changed to ' '. This caused join matches all over the place that I was not expecting. The missing user_name fields were supposed to have different default values. I fixed the default values in the machines table and excluded them with "where machines.User_name <> 'Unknown';" Now I am getting the results I expected. Probably nothing to learn here except understand your data better.

SQL Sum Query Behaving Strangely?

I'm having an issue getting this SQL query to work properly.
I have the following query
SELECT apps.*,
SUM(IF(adtracking.appId = apps.id AND adtracking.id = transactions.adTrackingId, transactions.payoutAmount, 0)) AS 'revenue',
SUM(IF(adtracking.appId = apps.id AND adtracking.type = 'impression', 1, 0)) AS 'impressions'
FROM apps, adtracking, transactions
WHERE apps.userId = '$userId'
GROUP BY apps.id
Everything is working, HOWEVER for the 'impressions' column I am generating in the query, I am getting a WAY larger number than there should be. For example, one matching app for this query should only have 72 for 'Impressions' yet it is coming up with a value of over 3,000 when there aren't even that many rows in the adtracking table. Why is this? What is wrong here?
Your problem is you have no join conditions, so you are getting every row of every table being joined in your query result - called a cartesian product.
To fix, change your FROM clause to this:
FROM apps a
LEFT JOIN adtracking ad ON ad.appId = a.id
LEFT JOIN transactions t ON t.adTrackingId = ad.id
You haven't provided the schema for your tables, so I guessed the names of the relevant columns - you may have to adjust them. Also, your transaction table may join to adtracking - it's impossible to know from your question, so agin you have have to alter things slightly. Hopefully you get the idea.
Edit:
Note: your group-by clause is incorrect. You either need to list every column of apps (not recommended), or change your select to only select the id column from apps (recommended). Change your select to this:
SELECT apps.id,
-- rest of query the same
Otherwise you'll get weird, incorrect, results.

Inserting millions of records with deduplication SQL

This is a theoretical scenario, and I am more than amateur when it comes to large scale SQL databases...
How would I go about inserting around 2million records into an existing database off 6million records (table1 into table2), whilst at the same time using email de-duplication (some subscribers may already exist in site2, but we don't want to insert those that already exist)?
I understand how to simply get the records from site 1 and add them into site 2, but how would we do this on such a large scale, and not causing data duplication? Any reading sources would be more than helpful for me, as ive found that a struggle.
i.e.:
Table 1: site1Subscribers
site1Subscribers(subID, subName, subEmail, subDob, subRegDate, subEmailListNum, subThirdParties)
Table 2: site2Subscribers
site2Subscribers(subID, subName, subEmail, subDob, subRegDate, subEmailListNum, subThirdParties)
I would try something like this:
insert into site2Subscribers
select * from site1Subscribers s1
left outer join site2Subscribers s2
on s1.subEmail = s2.subEmail
where s2.subEmail is null;
The left outer join along with the null check will return only those rows from site1Subscribers that have no matching entry in site2Subscribers.

MySQL: Why does this select query not find row when joined table has multiple results?

Title might be confusing, didn't quite know how to put it. Here's what i need to do. I have two tables, cronjobs and cronjob_seeds. I need to see if a cronjob exists before adding it to the database.
Consider these tables:
cronjobs:
-id- -callback_model- -callback_method-
1 movie_suggestion_model fetch_similar_movies
cronjob_seeds:
-cronjob_id- -seed-
1 seed1
1 seed2
Before adding a new cronjob, i need to see if the exact same cronjob exists in the database. I wrote the following query, but it doesn't work if the cronjob has multiple seeds. It works good if it only has one seed, but every time a cronjob has multiple seeds it returns nothing.
SELECT `id`
FROM (`cronjobs`)
INNER JOIN `cronjob_seeds` ON `cronjob_seeds`.`cronjob_id` = `cronjobs`.`id`
WHERE `cronjobs`.`callback_model` = 'movie_suggestion_model'
AND `cronjobs`.`callback_method` = 'fetch_similar_movies'
AND `cronjob_seeds`.`seed` = '1'
AND `cronjob_seeds`.`seed` = 10
Am i missing something? Should i be using another type of join?
And, off topic, but a seed is a parameter for the callback method, i just named it a little weird.
You should use IN clause
Change your query to:
SELECT `id`
FROM (`cronjobs`)
INNER JOIN `cronjob_seeds` ON `cronjob_seeds`.`cronjob_id` = `cronjobs`.`id`
WHERE `cronjobs`.`callback_model` = 'movie_suggestion_model'
AND `cronjobs`.`callback_method` = 'fetch_similar_movies'
AND `cronjob_seeds`.`seed` IN ('seed1', 'seed2')
Only to check if a cron entry exists, you don't need a join, unless you need to check if it exists and has specific seeds. To check only if a cron entry exists you need to do something like this:
SELECT `id`
FROM `cronjobs`
WHERE `cronjobs`.`callback_model` = 'movie_suggestion_model'
AND `cronjobs`.`callback_method` = 'fetch_similar_movies'
How come your query return result even when you had a single row for _cronjob_seeds_ . Cause the last two AND criteria conflict with each other. You should revise it as :
AND `cronjob_seeds`.`seed` BETWEEN '1' AND '10'
Also are you questioning the existance of a record in cronjob_seed or in cronjob? Your query parameters does not seem to be clear. Are you trying to check whether a specific cronjob with specific seeds exist? Tip: try to write the query in human language than sql

MySQL update table to fill nulls from another table

I have a table codes with fields id, code, issuedto, issuedtime which is pre-filled with items in code but which has many rows with NULLs in issuedto, issuedtime. I have another table entrants which has fields id, status.
I want to set codes.issuedto = winners.id for each row of winners with status = 'won'.
The problem is I don't have anything to join the tables on -- so I end up with a cross join and that's not what I want at all. What I really want is an inner join -- but without anything to join on. Anyone have any ideas?
EDIT: if I were doing this outside of SQL (which I might have to do?) the pseudocode would look something like:
rows = query("SELECT id FROM winners WHERE status='won'");
foreach (rows as r) {
query("UPDATE codes SET issusedto=" + r.id + ", issued=NOW() WHERE issuedto IS NULL LIMIT 1");
}
OP here. After some extensive searching and experimentation, I have come to the conclusion this cannot be done in SQL. I wrote a short script to do this work for me, similar to the pseudocode listed in the question. ACID compliance is achieved by transactions (check your DBMS for details if this is important).