Primary key on linked table - ms-access

I've a table linked to Outlook Contacts. It's useful to use it this way as it stays always up to date.
But I need it to have a primary key as it's useful for better query management. (Eg., if I'm not wrong, you can have an editable further query with two tables only if these two tables are joined on primary key fields.)
I couldn't get rid of it, and I see following way only but it's not actually satisfying me:
create a table equal to "outlook contacts" but static, manually (or with VBA) update it starting from the linked one. But it seems quite complicated.
Edit:
For better clarity let's assume the linked table is named OutlookContacts and, for easiness, has following 5 fields:
Company
LastName
FirstName
Email
MobileNumber

What I would do to help solve your issue is this:
Build a make table query that selects from the linked table into a new tables. i.e.:
SELECT
t1.Company
, t1.LastName
, t1.FirstName
, t1.Email
, t1.MobileNumber
, COUNT(*) AS RowID
INTO NewTbl
FROM yourTable t1
INNER JOIN yourTable t2 ON t1.Email>=t2.Email
GROUP BY
t1.Company
, t1.LastName
, t1.FirstName
, t1.Email
, t1.MobileNumber
This is just a sample query to show you how to get a rowid into your new table as your run the query.
2.Then run another saved query:
ALTER TABLE NewTbl ADD PRIMARY KEY (RowiD)
Then create a marco for AutoExec that fires both of these sequentially when anyone opens the database. BOOM solved.

Related

MYSQL drop duplicates of userid

I thought I'd made the column userid in my table "userslive" unique, but somehow must have made a mistake. I've seen multiple answers to this question, but I'm afraid of messing up again so I hope someone can help me directly.
So this table has no unique columns, but I've got a column "timer" which was the timestamp of scraping the data. If possible I'd like to drop rows with the lowest "timer" with duplicate "userid" column.
It's a fairly big table at about 2 million rows (20 columns). There is about 1000 duplicate userid which I've found using this query:
SELECT userid, COUNT(userid) as cnt FROM userslive GROUP BY userid HAVING (cnt > 1);
Is this the correct syntax? I tried this on a backup table, but I suspect this is too heavy for a table this big (unless left to run for a very long time.
DELETE FROM userslive using userslive,
userslive e1
where userslive.timer < e1.timer
and userslive.userid = e1.userid
Is there a quicker way to do this?
EDIT: I should say the "timer" is not a unique column.
DELETE t1.* /* delete from a copy named t1 only */
FROM userslive t1, userslive t2
WHERE t1.userid = t2.userid
AND t1.timer < t2.timer
fiddle
Logic: if for some record (in a copy aliased as t1) we can find a record (in a table copy aliased as t2) with the same user but with greater/later timer value - this record must be deleted.
I've done this in the past and the easiest way to solve this is to add an id column and then select userid, max(new_id) into a new table and join that for the delete. Something like this.
ALTER TABLE `userslive`
ADD `new_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
Now you have your new unique column and create a new table for selecting the ones to delete.
CREATE TABLE `users_to_delete`
AS
SELECT userid, new_id
FROM (
SELECT userid, max(new_id) new_id, count(*) user_rows
FROM `userslive`
GROUP BY 1
) dataset
WHERE user_rows > 1
Then use that to delete your duplicate rows by joining it into a DELETE statement like this:
DELETE `userslive` FROM `userslive`
INNER JOIN `users_to_delete` USING(userid,new_id);
Make sure you back everything up before you delete anything just in case.

Removing duplicate entries in an SQL table?

I did research but the answers were too complicated to convert to my schema and solution.
I have a table which I forgot to make a field unique in and now the insert has created lots and lots of items under the same field value. My table name is queue_items and the field is called item - how can I remove duplicates of item field?
I still want to be left with 1 item of the duplicates if that makes sense, but just delete any more than 1.
Here is what I've got so far
WITH CTE AS(
SELECT `item`
RN = ROW_NUMBER()OVER(PARTITION BY `item` ORDER BY `item`)
FROM `queue_items`
)
DELETE FROM CTE WHERE RN > 1
If you have a primary key like e.g. id you could try something like:
DELETE FROM
queue_items
WHERE
id
NOT IN (
SELECT MIN(id) FROM queue_items GROUP BY item
);
I would suggest emptying the table and repopulating it:
CREATE temp_qi AS
SELECT i.*
FROM (SELECT qi.*,
ROW_NUMBER()OVER(PARTITION BY `item` ORDER BY `item`) as seqnum
FROM `queue_items`
) qi
WHERE seqnum = 1;
ALTER TABLE drop_column seqnum;
TRUNCATE TABLE queue_items; -- backup before doing this!
INSERT INTO queue_items
SELECT * -- columns should be in the right order
FROM temp_qi;
Well that was s tricky one :) As far As I noticed you have a SQL-Table with Duplicate Entries, no Unique-Key (of course) and now simply want to get rid of the duplicates. I tried to recreate this using mySQL, which is not that easy for one can not DELETE / UPDATE and Querying to the same Table in mySQL per Definition.
Instead I had to follow this simple workaround:
Create a new TempTable, with the same structure as the original table
Copy every entry, to the new TempTable BUT group them by the duplicate_ID
DELETE original table
RENAME TempTable to the original table's name
In SQL you can do so by running the following queries - but make sure you have a backup, just in case.... :)
Workaround Delete duplicate SQL entries:
CREATE TABLE newTestTabelle LIKE TestTabelle;
//make sure table was created successfully before next step
INSERT INTO newTestTabelle
SELECT * FROM TestTabelle
GROUP BY myIndex;
//make sure copy was successfully done
DROP TABLE TestTabelle;
ALTER TABLE newTestTabelle RENAME TO TestTabelle;
Hint: I found a similar solution and very nice documentation for that under following link (http://www.mysqltutorial.org/mysql-delete-duplicate-rows/) - read for further information on topic

Delete all not referenced (by foreign key) records from a table in mysql

I have a address table which is referenced from 6 other tables (sometimes multiple tables). Some of those tables have around half a million records (and the address table around 750000 records). I want to have a periodical query running which deletes all records that are not referenced from any of the tables.
The following sub-queries is not a option, because the query never finishes - the scope is too big.
delete from address where address_id not in (select ...)
and not in (select ...) and not in (select ...) ...
What I was hoping was that I could use the foreign key constraint and I could simply delete all records for which the foreign key constraint does not stop me (because there is no reference to the table). I could not find a way to do this (or is there?). Anybody another good idea to tackle this problem?
You can try this ways
DELETE
address
FROM
address
LEFT JOIN other_table ON (address.id = other_table.ref_field)
LEFT JOIN other_table ON (address.id = other_table2.ref_field)
WHERE
other_table.id IS NULL AND other_table2.id IS NULL
OR
DELETE
FROM address A
WHERE NOT EXISTS (
SELECT 1
FROM other_table B
WHERE B.a_key = A.id
)
I always use this:
DELETE FROM table WHERE id NOT IN (SELECT id FROM OTHER table)
I'd do this by first creating a TEMPORARY TABLE (t) that is a UNION of the IDs in the 6 referencing tables, then run:
DELETE x FROM x LEFT JOIN t USING (ID) WHERE x.ID IS NULL;
Where x is the address table.
See 'Multiple-table syntax' here:
http://dev.mysql.com/doc/refman/5.0/en/delete.html
Obviously, your temporary table should have its PRIMARY KEY on ID. It may take some time to query and join, but I can't see a way round it. It should be optimized, unlike the multiple sub-query version.

Deleting multiple records from a very big table (query takes forever)

I am using the following query to delete multiple records except one from my table. It works well with small tables, but it got stuck when I tried it with a table that has >130000 records. The thing is, I don't even get an error. phpMyAdmin just gets stuck and the query ("loading... yellow line) basically takes forever.
My table structure
person_id (AI & PK)
person_name ( I want to delete multiple person_name records except one)
query
DELETE t2
FROM `person` t1
INNER JOIN `person` t2
ON t1.person_name = t2.person_name
AND t1.person_id < t2.person_id;
UPDATE : I don't have an index on person table. But my three other tables (person_job & person_image, book_who_wrote_it) contains foreign keys from person table (person_id)
First, do you have an index on person(person_name, person_id)? That would be the place to start.
Deleting lots of rows incurs overhead. Often, it is faster to put the results in another table and reinsert them:
create temporary table tmp_person as
select p.*
from person p join
(select person_name, max(person_id) as max_person_id
from person
) pp
on p.person_id = pp.max_person_id;
truncate table person;
insert into person
select * from tmp_person;
Be sure you validate tmp_person before truncating person! Truncate does not log the deletion of each row, so it is much, much, much faster than delete under most circumstances.
NOTE:
If you really only have two columns in person, then you can simplify the first query to:
create temporary table tmp_person as
select person_name, max(person_id) as max_person_id
from person;
try this
DELETE
FROM `person` t1
where person_id not in
(select * from
(select person_id from person group by person_name)x)

MySQL Update set Value only if flag = 0

I have this Query:
INSERT INTO `items` (`id`,`image`)
VALUES(112,'asdf.jpg'),(113,'foobar.png')
ON DUPLICATE KEY UPDATE
`id`VALUES(`id`),
`image` = IF(image_uploaded = 0, VALUES(`image`),image);
The worse: its properly working but not as i want.
What i want: The images should only be updated if the field "image_uploaded" is set to 0.
Any ideas?
The Background: I have a DB-Table with data. Now each night a cronjob calls an API-Fn to get new Data from another DB and write it down to my table. This function is getting all items from the second DB so its currently just overwriting my existing data. Now my Application allows changes on data i got from the 2nd DB and overwrites the changes in my own Table. So the Problem is: I need the ability to edit Data via my App AND update Data via API without colliding. The User may change the "image" but all other things should be updated from the 2nd DB. The Image should only be overwritten if it wasn't uploaded manually.
Without playing around with ON DUPLICATE KEY... I'm not sure, if it can handle this situation. I'd work around it by using another (temporary) table.
It's the same structure as your target_table plus a column (in the example sid) to indicate if the entry exists in your target_table or not.
CREATE TEMPORARY TABLE tmp_whatever (
sid int,
id int, image varchar(50)
);
Now we insert the data you want to insert into your target_table into the newly created table first and check with coalesce() and left joining, if the entry already exists. I'm assuming here, that id is your primary key.
INSERT INTO tmp_whatever (sid, id, image)
SELECT
COALESCE(t.id, 0),
id, image
FROM (
SELECT 112 AS id,'asdf.jpg' AS image
UNION ALL
SELECT 113,'foobar.png'
) your_values v
LEFT JOIN your_target_table t ON v.id = t.id;
Then we update the target_table...
UPDATE your_target_table t INNER JOIN tmp_whatever w ON t.id = w.id AND w.sid <> 0
SET t.image = w.image
WHERE t.image_uploaded = 0;
And finally we insert the rows not already existing...
INSERT INTO your_target_table (id, image)
SELECT
id, image
FROM tmp_whatever
WHERE sid = 0;
While I was writing this down, it came to my mind, that I might have had wrong assumptions on what your problem is. This
The worse: its properly working but not as i want.
is definitely not the way to ask a question or describe a problem. I answered because I have a good day :) (and it's the reason why you get downvotes, btw)
Anyway, another cause of "not as i want" could be, that you're missing a unique index in your table. Though a primary key is a unique key, afaik/iirc ON DUPLICATE KEY relies on a unique index on another column to work correctly.