I have a large database with 300,000 rows (1.6 GB). I need to delete them all EXCEPT the ones that has the following features:
main_sec=118
main_sec=Companies
type=SWOT
Here is the code I prepared, but somehow, it's deleting all the rows of the table:
DELETE FROM `swots`
WHERE (main_sec <> '118') OR
(main_sec <> 'Companies') OR
(type <> 'SWOT');
Please help me to understand where the mistake is.
DELETE FROM `swots`
WHERE main_sec not in ('118', 'Companies')
and type <> 'SWOT'
It would be faster to insert the rows that you want to keep (assuming they are fewer then the remaining rows) in a new table like :
INSERT INTO main_sec_new
SELECT
*
FROM main_sec
WHERE main_sec IN ('118','Companies')
and type = 'SWOT'
And then just drop the old table
Try this:
DELETE FROM `swots`
WHERE (main_sec not in ('118', 'Companies')) OR
(type <> 'SWOT');
The problem is that main_sec is always not equal to one of those two values in a given record. So, every record meets the where condition in your version.
Related
I'm not a DB guy and I've looked around here to look for an answer in similar questions but couldn't find one that solves this particular problem:
I have 2 tables - Each with 3 columns (PrimaryKey1, Table1Coln1, Table1Coln2, PrimaryKey2, Table2Coln1, Table2Coln2).
What I'm trying to do is copy values from Table2Coln2 and paste them into Table1Coln2 wherever values in Table1Coln1 & Table2Coln1 are equal. To complicate matters, there are multiple rows with the same values in both corresponding columns in both tables.
I've tried this:
UPDATE Table1
SET Table1.Table1Coln2 = Table2.Table2Coln2
WHERE Table1.Table1Coln1 = Table2.Table2Coln1
When I run the query, it opens a dialog box asking me to enter a value for Table2.Table2Coln2 ?!
Can someone please tell me what I'm doing wrong here?
You should Join Table1 and Table2:
'Clasic' SQL (used in MySQL):
UPDATE Table1, Table2
SET Table1.Table1Coln2 = Table2.Table2Coln2
WHERE Table1.Table1Coln1 = Table2.Table2Coln1
MS Sql (used in Access):
UPDATE Table1 Inner Join Table2 On Table1.Table1Coln1 = Table2.Table2Coln1
SET Table1.Table1Coln2 = Table2.Table2Coln2
I hope I can explain this to make sense lol.
I am trying to copy variables from one hats_old.red to hats_new.red that match hats_new.name in both tables, if they do not match then i need it to do nothing so it does not null the value or set it to 0.
This is as far as ive gotten. This changes unmatched to 0 which i am trying to avoid and cannot figure the rest out.
This is for Mysql
Thank you
UPDATE hats_new
SET hats_new.red = (
SELECT hats_old.red
FROM hats_old
WHERE hats_old.name = hats_new.name LIMIT 1
);
An update with a join should do the trick:
UPDATE hats_new hn
JOIN hats_old ho ON hn.name = oh.name
SET hn.red = ho.red
What I am trying to do is reduce the time needed to aggregate data by producing a roll-up table of sorts. When I insert a record, an after insert trigger is fired which will update the correct row. I would update all of the columns of the roll-up table if I need to, but since there are 25 columns in the table and each insert will only update 2 of them, I would rather be able to dynamically select the columns to update. My current update statement in the after insert trigger looks similar to this:
update peek_at_chu.organization_data_state_log odsl
inner join ( select
lookUpID as org_data_lookup,
i.interval_id,
peek_at_chu.Get_Time_Durration_In_Interval1('s', new.start_time, new.end_time, i.start_time, i.end_time) as time_in_int,
new.phone_state_id
from
(peek_at_chu.interval_info i
join peek_at_chu.interval_step int_s on i.interval_step_id = int_s.interval_step_id)) as usl on odsl.org_date_lookup_id = usl.org_data_lookup
and odsl.interval_id = usl.interval_id
set
total_seconds = total_seconds + usl.time_in_int,
case new.phone_state_id
when 2 then
available_seconds = available_seconds + time_in_int
end;
In this, lookUpID is a variable previously declared in the trigger. The field that will dictate which field of the roll-up table to update is new.phone_state_id. The phone_state_id's are not consistent, that is some numbers are skipped in this table, so an update based on column number is out the window unless I create a mapping.
The case option throws an error but I am hoping to use something similar to that instead of 25 if statements if I can.
You have to update all the columns, but use a conditional to determine whether to give it a new value or keep the old value:
set total_seconds = total_seconds + usl.time_in_int,
available_seconds = IF(new.phone_state_id = 2, available_seconds + time_in_int, available_seconds)
Repeat the pattern in the last line for all the other columns that need to be updated conditionally.
I have three tables
glSalesJournal
HMISAdd
HMISMain
Now what i am trying to do is add the glSalesJournal amt with HMISAdd amt while grouping up with various Fields and inserting the result into glSalesJournal
The glSalesJournal contains 633173 records
The HMISAdd contains 4193 records
HMISAdd and glSalesJournal contains the same columns which are
loc
glAcct
glSubAcct
batchNbr
contractNbr
amt
I added indexes to the table still the results are the same.
Here is my code:
INSERT INTO hmismain
(loc,
glacct,
subacct,
batchnbr,
contractnbr,
amt)
SELECT glsalesjournal.loc,
glsalesjournal.glacct,
glsalesjournal.glsubacct,
( glsalesjournal.amt + hmisadd.amt ) AS sumAmt,
glsalesjournal.batchnbr,
glsalesjournal.salescontnbr
FROM glsalesjournal
LEFT OUTER JOIN hmisadd
ON ( glsalesjournal.loc = hmisadd.loc
AND glsalesjournal.glacct = hmisadd.glacct
AND glsalesjournal.glsubacct = hmisadd.subacct
AND glsalesjournal.batchnbr = hmisadd.batchnbr
AND glsalesjournal.salescontnbr = hmisadd.contractnbr )
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
The time taken by the script to execute is more than 2 hours. Even when I limit the Records to 100 the time taken is the same.
Can someone please guide me how can I optimize the script.
Thanks
1) It looks like it's a one off query, am I correct here? If not than you are inserting the same data into hmismain table every time.
2) You are grouping on fields from TWO separate tables, so no amount of indexing will ever help you. The ONLY index that will help is an index over a view linking these two tables in the same way.
Further note:
What is the point of
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
You are grouping the data by the same fields twice
glsalesjournal.loc, hmisadd.loc
glsalesjournal.glacct, hmisadd.glacct,
...
Remove the duplicates from GROUP BY and it should run fast
Did you add an index on this fields:
glSalesJournal.loc
glSalesJournal.glAcct
glSalesJournal.glSubAcct
glSalesJournal.batchNbr
glSalesJournal.salesContNbr
HMISAdd.Loc
HMISAdd.GlAcct
HMISAdd.SubAcct
HMISAdd.batchNbr
HMISAdd.contractNbr
If this fields are unindexed, it will perform fulltable scan for each individual record thus causing slow performance.
MySQL Create Index Syntax
I am importing data to a table structured: content_id|user_id|count - all integers all comprise the composite primary key
The table I want to select it from is structured: content_id|user_id
For reasons quite specific to my use case, I will need to fire quite a lot of data into this regularly enough to want a pure MySQL solution
insert into new_db.table
select content_id,user_id,xxx from old_db.table
I want each row to go in with xxx set to 0, unless this would create a duplicate key, in which case I wish to increment the number, for the current user_id/content_id combination
Not being a MySQL expert, I tried a few options like trying to populate xxx by selecting from the target table during insert, with no luck. Also tried using ON DUPLICATE KEY to increment counters instead of the usual UPDATE. But it all seemed a bit daft so I thought I would come here!
Any ideas anyone? I have a backup option of wrapping this in PHP, but it would drastically raise the overall running time of the script in which this would be the only non-pure MySQL part
Any help really appreciated. thanks in advance!
--edit
this may sound really awful in principle. but id settle for a way to do it in an update after entering random numbers (i have sent in random numbers to allow me to continue other work at the moment) - and this is a purely dev setup
--edit again
12|234
51|45
51|45
51|45
23|67
would ideally insert
12|234|0
51|45|0
51|45|1
51|45|2
23|67|0
INSERT INTO new_db.table (content_id, user_id, cnt)
SELECT old.content_id, old.user_id, COUNT(old.*) - 1 FROM old_db.table old
GROUP BY old.content_id, old.user_id
this would be the way I would go, so if 1 entry it would put 0 on cnt, for more it would just put 1-2-3 etc.
Edit:
Your correct answer would be somewhat complicated but I tested it and it works:
INSERT INTO newtable(user_id,content_id,cnt)
SELECT o1.user_id, o1.content_id,
CASE
WHEN COALESCE(#rownum, 0) = 0
THEN #rownum:=c-1
ELSE #rownum:=#rownum-1
END as cnt
FROM
(SELECT user_id, content_id, COUNT(*) as c FROM oldtable
GROUP BY user_id, content_id ) as grpd
LEFT JOIN
(SELECT oldtable.* FROM oldtable) o1 ON
(o1.user_id = grpd.user_id AND o1.content_id = grpd.content_id)
;
Assuming that in the old db table (source), you will not have the same (content_id, user_id) combination, then you can import using this query
insert newdbtable
select o.content_id, o.user_id, ifnull(max(n.`count`),-1)+1
from olddbtable o
left join newdbtable n on n.content_id=o.content_id and n.user_id=o.user_id
group by o.content_id, o.user_id;