Index: wp-admin/admin-db.php
===================================================================
--- wp-admin/admin-db.php	(revision 4840)
+++ wp-admin/admin-db.php	(working copy)
@@ -154,6 +154,7 @@
 	global $wpdb;
 
 	$cat_ID = (int) $cat_ID;
+	$default_cat = get_option('default_category');
 
 	// Don't delete the default cat.
 	if ($cat_ID == get_option('default_category'))
@@ -164,15 +165,29 @@
 	$parent = $category->category_parent;
 
 	// Delete the category.
-	$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'");
+	if ( !$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'") )
+		return 0;
 
 	// Update children to point to new parent.
 	$wpdb->query("UPDATE $wpdb->categories SET category_parent = '$parent' WHERE category_parent = '$cat_ID'");
 
-	// TODO: Only set categories to general if they're not in another category already
-	$default_cat = get_option('default_category');
-	$wpdb->query("UPDATE $wpdb->post2cat SET category_id='$default_cat' WHERE category_id='$cat_ID'");
+	// Only set posts and links to the default category if they're not in another category already
+	$posts = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE category_id='$cat_ID'");
+	$only_in_deleted = array();
+	foreach ( (array) $posts as $post_id ) {
+		$other_cat_count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat WHERE category_id <> '$cat_ID' AND post_id = '$post_id'");
+		if ( 0 == $other_cat_count ) // exists only in the to-be-deleted category
+			$only_in_deleted[] = $post_id;
+	}
 
+	if ( $only_in_deleted ) {
+		$only_in_deleted = implode(',', $only_in_deleted);
+		$wpdb->query("UPDATE $wpdb->post2cat SET category_id='$default_cat' WHERE category_id='$cat_ID' AND post_id IN($only_in_deleted)");
+	}
+
+	// Now, all remaining posts in $cat_ID should exist in another category, so we can do:
+	$wpdb->query("DELETE FROM $wpdb->post2cat WHERE category_id='$cat_ID'");
+
 	wp_cache_delete($cat_ID, 'category');
 	wp_cache_delete('all_category_ids', 'category');
 

