CAML doesn't have anything built in for that, so you are limited to making two async calls with the JavaScript client object model.
The code snippet below checks a list called "Training Progress" for an item created by the current user. It updates it if it exists or creates it if it doesn't exist.
ExecuteOrDelayUntilScriptLoaded(
function(){
var numRight = 12; /* dummy data */
var clientContext = new SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle("Training Progress");
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><Query><Where><Eq><FieldRef Name=\"Author\" LookupId=\"TRUE\"/><Value Type=\"Lookup\">" + _spUserId + "</Value></Eq></Eq></Where></Query><RowLimit>1</RowLimit></View>");
var currentProgress = list.getItems(camlQuery);
clientContext.load(currentProgress);
clientContext.executeQueryAsync(Function.createDelegate(this,
function(){ /* List exists, grab the user's item if it exists */
var itemEnumerator = currentProgress.getEnumerator();
var itemId = -1;
while(itemEnumerator.moveNext()){
var item = itemEnumerator.get_current();
itemId = item.get_item("ID");
}
if(itemId == -1){ /* Create item in list */
var itemCreateInfo = new SP.ListItemCreationInformation();
var newItem = list.addItem(itemCreateInfo);
newItem.set_item('Title',_spUserId);
newItem.set_item('Certification',numRight);
newItem.update();
clientContext.load(newItem);
}else{ /* Update item in list */
var item = list.getItemById(itemId);
item.set_item('Certification',numRight);
item.update();
clientContext.load(item);
}
clientContext.executeQueryAsync();
}),Function.createDelegate(this,
function(sender,args){ /* List doesn't exist. */
alert(args.get_message());
}));
},"SP.JS");
You can even take this a step further and create the list if it doesn't exist, but that assumes the code is running under the context of someone with access to create lists.