|
mercatroid Wanderer
Joined: 06 Dec 2004 Posts: 59
|
Posted: Tue Feb 19, 2008 1:34 am
Database Duplicates |
zMud ver 7.21
Anyone know an easy way to remove duplicate entries in a zMud database? |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Feb 19, 2008 11:31 am |
It has been a while since I really played with the database, so this might need some tweaking. Also this is entirely off the top of my head.
Code: |
#DBFIRST
#WHILE (%rec!="") {
DBQuery=%query(%concat("(&",%delnitem(%expanddb(%rec,"=",") and (&"),1),")"))
#IF (%numitems(@DBQuery)>1) {#SHOW Duplicates found @DBQuery}
#DBNEXT
} |
That should find the duplicates deleteing them would be a matter of looping through the query variable and removing some. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Tue Feb 19, 2008 12:47 pm |
Code: |
#var seen {}
#var remo {}
#DBFIRST
#WHILE (!%null(%rec)) {
#var cd %replace(%replace(%delkey(%rec,"Num"),%char(29),%char(19)),%char(30),%char(20))
#if (%ismember(@cd,@seen) and !%null(@seen)) {#var remo %additem(%db(%rec,"Num"),@remo)} {#additem seen {@cd}}
#DBNEXT
}
#SHOW Duplicates found @remo |
|
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
mercatroid Wanderer
Joined: 06 Dec 2004 Posts: 59
|
Posted: Wed Feb 20, 2008 1:09 am |
Sweet!
Now I'm going to make it a little more complicated:
Say I want to removed entries with one field duplicated. For example:
Code: |
# Name Class Race
1 Bob Mage Human
2 Dave Ranger Elf
3 John Warrior Human
4 Steve Mage Human
5 Steve Mage Elf
6 Steve Cleric Dwarf |
Steve is listed 3 times. I want to purge entries that have a duplicate name, like entries 5 and 6 in my example.
The whole entry should be removed, only the 1st entry of each name should be kept.
Also, over time my database accumulates entries with a blank field (just a product of lag, mud sending erroneous data, etc)...would be good to remove any entry with a blank field (any blank field) as well. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Wed Feb 20, 2008 3:46 am |
Code: |
#var deletelist {}
#for %dups(%dblist(Name)) {
#var dbrep %delnitem(%query((&Name={%i})),1)
#if (!%null(@dbrep)) {#var deletelist %concat(@deletelist,|,@dbrep)} {}
}
#var deletelist %dups(@deletelist)
#SHOW Duplicates found @deletelist |
|
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
mercatroid Wanderer
Joined: 06 Dec 2004 Posts: 59
|
Posted: Wed Feb 20, 2008 11:31 pm |
Some explaination of that, Dharkael?
I made an alias with that code in it, ran the alias, and received: "Duplicates found", like the #SHOW at the end of your code, without a value for @deletelist. Nothing else happened, and my database still has duplicates.
I assume I'm doing something wrong. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Thu Feb 21, 2008 12:51 am |
Is the database window open when you're running the alias?
I think the database window has to be open when running code to affect the DB.
Type #SHOW %dblist(Name)
and it should show a stringlist of all the values in the Name column of your DB
I created a database named abc with the data you gave above and created an alias with the code I posted above.
Here's a line by line of what happens
=================================
Line 1:
Initialize an empty variable named deletelist
Line 2:
Call %dblist specifying Name as the column of values to return.
This returns a stringlist with every value in the name column. Bob|Dave|John|Steve|Steve|Steve
use %dups to remove any duplicate values now we have Bob|Dave|John|Steve
using #for execute the code within the braces following #for once for each item in the list.
Line 3:
use the %query function to get a list of record ids that have "Steve" for example in the name column
%query((&Name=Steve)) will return the list 4ab|5ab|6ab
we use %delnitem to remove the first item in the list (if there is only 1 item, meaning there are no duplicates we left with an empty list
we assign this list to the variable dbrep , in our example @dbrep is now 5ab|6ab
Line 4:
if @dbrep is not empty then we add its contents to the deletelist variable, if it is empty (meaning there was no duplicates for this name), we do nothing
Line 5:
loop through the list repeating lines 3 and 4 for each Name we got in line 2
Line 6:
use %dups to remove any duplicates, or empty items in the variable deletelist
Line 7:
Display the list of records we have to delete.
==================================
Thats it, now you can actually clear these duplicates by doing something like
#for @deletelist {#DBDELETE %i}
Hope that clears it up a bit. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
mercatroid Wanderer
Joined: 06 Dec 2004 Posts: 59
|
Posted: Wed Mar 12, 2008 5:11 pm |
It takes running it several (15+) times to clear out all the duplicates, finding/ removing a few each time, but it works.
Thanks! |
|
|
|
|
|