Can we Use "Case" in a ColdFusion Query-of-Query - sql

I am applying case in ColdFusion query of query but it's throwing an error.
Query:
<cfquery name="qEmployees1" dbtype="query">
select (
case
when ISNUMERIC(u.userdefined)=1
then right('00000000'+u.userdefined,8)
else userdefined
end
) as hello
from all_employees
order by hello ASC
</cfquery>
Error message:
Encountered "when" at line 3, column 22. Was expecting one of:
"AND" ... "BETWEEN" ... "IN" ... "IS" ... "LIKE" ... "NOT" ...
"OR" ... ")" ... "=" ... "." ... "!=" ... "#" ... "<>" ...
">" ... ">=" ... "<" ... "<=" ... "+" ... "-" ... "*" ...
"||" ... "/" ... "**" ... "(" ...

Update:
The original suggestion isn't going to work due to it only looking at a single row. Really you need to loop through your all_employees recordset and apply it to each individual row.
You might be able to achieve this without QoQ if you are just outputting the results to the page. Like this:
<cfoutput>
<cfloop query="all_employees">
<cfif isNumeric(all_employees.userdefined)>
#Right('00000000'&all_employees.userdefined,8)#
<cfelse>
#all_employees.userdefined#
<cfif>
</cfloop>
</cfoutput>
Original Answer:
How about something like this?:
<cfquery name="qEmployees1" dbtype="query">
SELECT
<cfif isNumeric([all_employees].[u.userdefined])>
right('00000000'+u.userdefined,8)
<cfelse>
u.userdefined
</cfif> AS hello
FROM all_employees
ORDER by hello
</cfquery>
I have not tested this but I don't think having dot notation in the SQL column name will work correctly in this case. I enclosed it in square brackets anyway.

In case anyone else decides to try the QoQ below, one very important thing to note is that even if it executes without error, it's NOT doing the same thing as CASE. A CASE statement applies logic to the values within each row of a table - individually. In the QoQ version, the CFIF expression does not operate on all values within the query. It only examines the value in the 1st row and then applies the decision for that one value to ALL rows in the query.
Notice how the QoQ below (incorrectly) reports that all of the values are numeric? While the database query (correctly) reports a mix of "Numeric" and "Non-numeric" values. So the QoQ code is not equivalent to CASE.
TestTable Data:
id userDefined
1 22
2 AA
3 BB
4 CC
Database Query:
SELECT CASE
WHEN ISNUMERIC(userDefined)=1 THEN 'Number: '+ userDefined
ELSE 'Not a number: ' + userDefined
END AS TheColumnAlias
FROM TestTable
ORDER BY ID ASC
Database Query Result:
QoQ
<cfquery name="qQueryOfQuery" dbtype="query">
SELECT
<cfif isNumeric(qDatabaseQuery2.userDefined)>
'Number: '+ userDefined
<cfelse>
'Not a number: ' + userDefined
</cfif>
AS TheColumnAlias
FROM qDatabaseQuery2
ORDER by ID
</cfquery>
QoQ Result

EDIT:
I thought about this one and decided to change it to an actual answer. Since you're using CF2016+, you have access to some of the more modern features that CF offers. First, Query of Query is a great tool, but it can be very slow. Especially for lower record counts. And then if there are a lot of records in your base query, it can eat up your server's memory, since it's an in-memory operation. We can accomplish our goal without the need of a QoQ.
One way we can sort of duplicate the functionality that you're looking for is with some of the newer CF functions. filter, each and sort all work on a query object. These are the member function versions of these, but I think they look cleaner. Plus, I've used cfscript-syntax.
I mostly reused my original CFSCript query (all_employees), that creates the query object, but I added an f column to it, which holds the text to be filtered on.
all_employees = QueryNew("userdefined,hello,f", "varchar,varchar,varchar",
[
["test","pure text","takeMe"],
["2","number as varchar","takeMe"],
["03","leading zero","takeMe"],
[" 4 ","leading and trailing spaces","takeMe"],
["5 ","extra trailing spaces","takeMe"],
[" 6","extra leading spaces","takeMe"],
["aasdfadsf","adsfasdfasd","dontTakeMe"],
["165e73","scientific notation","takeMe"],
["1.5","decimal","takeMe"],
["1,5","comma-delimited (or non-US decimal)","takeMe"],
["1.0","valid decimal","takeMe"],
["1.","invalid decimal","takeMe"],
["1,000","number with comma","takeMe"]
]
) ;
The original base query didn't have a WHERE clause, so no additional filtering was being done on the initial results. But if we needed to, we could duplicate that with QueryFilter or .filter.
filt = all_employees.filter( function(whereclause){ return ( whereclause.f == "takeMe"); } ) ;
This takes the all_employees query and applies a function that will only return rows that match our function requirements. So any row of the query where f == "takeMe". That's like WHERE f = 'takeMe' in a query. That sets the new filtered results into a new query object filt.
Then we can use QueryEach or .each to go through every row of our new filtered query to modify what we need to. In this case, we're building a new array for the values we want. A for/in loop would probably be faster; I haven't tested.
filt.each(
function(r) {
retval.append(
ISNUMERIC(r.userDefined) ? right("00000000"&ltrim(rtrim((r.userdefined))),8) : r.userDefined
) ;
}
) ;
Now that we have a new array with the results we want, the original QoQ wanted to order those results. We can do this with ArraySort or .sort.
retval.sort("textnocase") ;
In my test, CF2016 seemed to pass retval.sort() as a boolean and didn't return the sorted array, but CF2018 did. This was expected behavior, since the return type was changed in CF2018. Regardless, both will sort the retval array, so that when we dump the retval array, it's in the chosen order.
And as I always suggest, load test on your system with your data. Like I said, this is only one way to go about what you're trying to do. There are others that may be faster.
https://cffiddle.org/app/file?filepath=dedd219b-6b27-451d-972a-7af75c25d897/54e5559a-b42e-4bf6-b19b-075bfd17bde2/67c0856d-bdb3-4c92-82ea-840e6b8b0214.cfm
(CF2018) > https://trycf.com/gist/2a3762dabf10ad695a925d2bc8e55b09/acf2018?theme=monokai
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-m-r/queryfilter.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-m-r/queryeach.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraysort.html
ORIGINAL:
This is more of a comment than an answer, but it's much too long for a comment.
I wanted to mention a couple of things to watch out for.
First, ColdFusion's isNumeric() can sometimes have unexpected results. It doesn't really check to see if a value is a number. It checks if a string can be converted to number. So there are all sorts of values that isNumeric() will see as numeric. EX: 1e3 is scientific notation for 1000. isNumeric("1e3") will return true.
My second suggestion is how to deal with leading and trailing space in a "numeric" value, EX: " 4 ". isNumeric() will return true for this one, but when you append and trim for your final value, it will come out as "000000 4". My suggestion to deal with these is to use val() or ltrim(rtrim()) around your column. val() will reduce it to a basic number (" 1.0 " >> "1") but ltrim(rtrim()) will retain the number but get rid of the space (" 1.0 " >> "1.0") and also retain the "scientific notation" value (" 1e3 " >> "1e3"). Both still miss 1,000, so if that's a concern you'll need to handle that. But the method you use totally depends on the values your data contains. Number verification isn't always as easy as it seems it should be.
I've always been a firm believer in GIGO -- Garbage In, Garbage Out. I see basic data cleansing as part of my job. But if it's extreme or regular, I'll tell the source to fix it or their stuff won't work right. When it comes to data, it's impossible to account for all possibilities, but we can check for common expectations. It's always easier to whitelist than it is to blacklist.
<cfscript>
all_employees = QueryNew("userdefined,hello", "varchar,varchar",
[
["test","pure text"],
["2","number as varchar"],
["03","leading zero"],
[" 4 ","leading and trailing spaces"],
["5 ","extra trailing spaces"],
[" 6","extra leading spaces"],
["165e73","scientific notation"],
["1.5","decimal"],
["1,5","comma-delimited (or non-US decimal)"],
["1.0","valid decimal"],
["1.","invalid decimal"],
["1,000","number with comma"]
]
)
//writedump(all_employees) ;
retval = [] ;
for (r in all_employees) {
retval.append(
{
"1 - RowInput" : r.userdefined.replace(" ","*","all") , // Replace space with * for output visibility.
"2 - IsNumeric?" : ISNUMERIC(r.userdefined) ,
"3 - FirstOutput": ( ISNUMERIC(r.userDefined) ? right("00000000"&r.userdefined,8) : r.userDefined ) ,
"4 - ValOutput" : ( ISNUMERIC(r.userDefined) ? right("00000000"&val(r.userdefined),8) : r.userDefined ) ,
"5 - TrimOutput" : ( ISNUMERIC(r.userDefined) ? right("00000000"&ltrim(rtrim((r.userdefined))),8) : r.userDefined )
}
) ;
}
writeDump(retval) ;
</cfscript>
https://trycf.com/gist/03164081321977462f8e9e4916476ed3/acf2018?theme=monokai

What are you trying to do exactly? Please share some context of the goal for your post.
To me it looks like your query may not be formatted properly. It would evalusate to something like:
select ( 0000000099
) as hello
from all_employees
order by hello ASC
Try doing this. Put a <cfabort> right here... And then let me know what query was produced on the screen when you run it.
<cfquery name="qEmployees1" dbtype="query">
select (
case
when ISNUMERIC(u.userdefined)=1
then right('00000000'+u.userdefined,8)
else userdefined
end
) as hello
from all_employees
order by hello ASC
<cfabort>
</cfquery>

<cfquery name="qEmployees1" dbtype="query">
SELECT
(
<cfif isNumeric(all_employees.userdefined)>
right('00000000'+all_employees.userdefined,8)
<cfelse>
all_employees.userdefined
</cfif>
) AS hello
FROM all_employees
ORDER by hello
</cfquery>
it is the syntax free answer thanks to #volumeone

Related

cfsavecontent display double apostrophe in SQL statement

I have several OR in my SQL statement so I want to save a chuck of it in a cfsavecontent. Here is that part:
<cfsavecontent variable="checkDepartment">
<cfif #wrkDept# EQ #dept[2][1]#>
Department = 'Health' AND
<cfelse>
Department = '#wrkDept#' AND
</cfif>
</cfsavecontent>
But the error I get on the page shows 2 sets of apostrophes around the word Health.
SQL
SELECT COUNT(*) AS numItems
FROM IT_PROJECTS
WHERE
Department = ''Health'' AND
status = 'Cancelled'
Can anyone help me to only get a single apostrophe? Thanks
So this answer seems a lot more complicated than it really is. And without knowing specifically what your query looks like (re:OR conditions), I'm not really sure how to structure it. It can be better. The goal should be to make one single trip to your SQL server with the query that makes the most sense for the data you're trying to get. I'm not sure what you are trying to do with cfsavecontent, but I don't think you need it.
The bulk of my example query (https://trycf.com/gist/4e1f46bfa84a6748aced0f9ee8221c6d/acf2016?theme=monokai) is setup. I chose to go with a cfscript format, because as Redtopia said, I also find it much easier to build a dynamic query in cfscript.
After initial setup, I basically just script out the variables I'll use in my final queryExecute().
// Base query.
qry = "SELECT count(*) AS theCount FROM IT_PROJECTS WHERE 1=1 " ;
// This is our dynamic filter that we build below.
qfilter = {} ;
// Query options.
opts = { "dbtype":"query" } ;
After we have our base, I build up the dynamic part of the query. This is the part that will likely change quite a bit depending on your current needs and setup.
For the first part, I basically replaced your cfif with a ternary evaluation. I'm not sure how your data plays into the evaluation of dept or where that array comes from. But from there I build a basic included statement of the query and set up the queryparam values for it. Then I add a second check that will pick a different set of values for the query (currently based on even/odd seconds). Again, I'm not sure of the intent of your query here, so I just made something dynamic.
//////////// BUILD DYNAMIC FILTER ////////////
qdept = ( wrkDept == dept[2][1] ) ? 'Health' : wrkDept ;
/// This one is an included filter:
qry &= " AND department = :dpt AND status = :sts " ;
qfilter.dpt = {"value":qdept,"cfsqltype":"CFSQLVARCHAR"} ;
qfilter.sts = {"value":"Cancelled","cfsqltype":"CFSQLVARCHAR"} ;
/// Adding Dynamic ORs
// Dynamically set status based on even/odd seconds.
qStatus = ( now().second()%2==0) ? "Cancelled" : "Active" ;
qry &= " OR ( department = :dpt2 AND status = :sts2 ) " ;
qfilter.dpt2 = {value:"IT",cfsqltype:"CFSQLVARCHAR"} ;
qfilter.sts2 = {value:qStatus,cfsqltype:"CFSQLVARCHAR"} ;
This gives us a SQL string that looks like:
SELECT count(*) AS theCount
FROM IT_PROJECTS
WHERE 1=1
AND department = :dpt AND status = :sts
OR
( department = :dpt2 AND status = :sts2 )
With a SQL statement, the placement of AND and OR conditions can greatly impact the results. Use parenthesis to group conditions how you need them.
After we've built the query string, we just have to plug it and our queryparams into the queryExecute().
result = queryExecute( qry , qfilter , opts ) ;
And if we want to output our data, we can go:
writeOutput("There are " & result.theCount & " records." ) ;
Which gives us:
There are 8 records.
Again, I don't know what your main conditions look like. If you can give me an example of a query with a bunch of ORs and ANDs, I'll try to modify this for you.

Can we append a DateTime to an array with the ArrayAppend() function of ColdFusion?

ERROR:Can't cast Object type [DateTime] to a value of type [Array]
<cfset Seniority=ArrayNew(1)>
<CFLOOP QUERY="all_employees">
<cfif isNull(all_employee.TimeInPositionDate) >
<cfset ArrayAppend(Seniority,all_employee.hiredate)>
<cfelse>
<cfset ArrayAppend(Seniority,all_employee.TimeInPositionDate)>
</cfif>
</CFLOOP>
Your issue stems form the variable lookup in CFML. While you're inside a query loop, ColdFusion will pull from the query scope before your variables scope. Due to there being a column in your query also called Seniority your code reads the same as ArrayAppend(all_employees.Seniority,all_employees.hiredate);
Changing the name of your array will solve the issue at hand.
<cfset all_employees = queryNew(
"Id,TimeInPositionDate,Hiredate,Seniority",
"Integer,Timestamp,Timestamp,Timestamp",
[
{"Id":1,"HireDate":Now(),"Seniority":Now()},
{"Id":2,"HireDate":Now(),"TimeInPositionDate":Now(),"Seniority":Now()}
]
)>
<cfset arrSeniority=ArrayNew(1)>
<CFLOOP QUERY="all_employees">
<cfif isNull(all_employees.TimeInPositionDate) >
<cfset ArrayAppend(arrSeniority,all_employees.hiredate)>
<cfelse>
<cfset ArrayAppend(arrSeniority,all_employees.TimeInPositionDate)>
</cfif>
</CFLOOP>
<cfdump var="#arrSeniority#"/>
I still think looping is much easier in CFScript (not to mention the fact that it just looks cleaner to me. Anyway, I can knock this down to essentially one line of code (beyond the array creation and looping code).
First, I set up my fake query object:
all_employees = QueryNew(
"id, TimeInPositionDate, hiredate" ,
"integer, date, date" ,
[
{
id:1 ,
TimeInPositionDate: "2018-01-01" ,
hiredate: "2017-01-01"
} ,
{
id:2 ,
// TimeInPositionDate: Not defined, so NULL
hiredate: "2017-02-01"
} ,
{
id:3 ,
TimeInPositionDate: "2018-03-01"
//hiredate: Not defined, so NULL
} ,
{
id:4
//TimeInPositionDate: Not defined, so NULL
//hiredate: Not defined, so NULL
}
]
);
I have created 3 rows. 1 full row, 1 with just a TimeInPositionDate, 1 with just a hiredate and 1 with neither. ColdFusion has always been a little odd with how it treats null, and it doesn't always mesh up well with a SQL query. In our fake query, we just don't define the rows we want to be null.
Next I create my array:
Seniority = [] ;
We don't have to use ArrayNew() to make an array. We can just use implicit notation to be much shorter.
Next we use a for/in loop around our query to append row data to our new array.
for (r in all_employees) {
Seniority.append( len(r.TimeInPositionDate) ? r.TimeInPositionDate : r.hiredate ) ;
}
Here, we're using the append() member function to add to our Seniority array. We also use a ternary operation to pick which value we want to add. It basically says that if there is a length to TimeInPositionDate for that row, then we use the first condition (TimeInPositionDate), otherwise we use hiredate.
I though about using an Elvis Operator...
Seniority2.append( q.TimeInPositionDate ?: q.hiredate ) ;
..., but since the query is likely returning q.TimeInPositionDate="" instead of an actual null value, then the first value is technically defined and gets chosen. That would work on a true null, but an empty string isn't a null.
You could probably also use each() or some other loopish function to iterate through your query object, but I've found for/in loops to usually be faster in cases like this. You'll have to test.
You can play with the full thing at:
https://cffiddle.org/app/file?filepath=de107907-234c-4df8-9386-02a288e53313/fdf21791-6cc4-4c55-b923-ad7726efa8ee/b3b6b906-8e3a-4f6b-9ec8-65845efc40f1.cfm
EDIT: NULLs can be so much fun. If we drop back into some Java, we can get an actual null value from the query rather than the cfquery-converted empty string, and show that Elvis is still in the building.
all_employees.getDate("TimeInPositionDate") ?: all_employees.getDate("hiredate") ) ;
Since Java's getDate() on a query will get the actual value and can handle a null, that correctly chooses the 2nd option for rows where TimeInPositionDate is null. That said, while I do appreciate the integration of Java and ColdFusion, I do not recommend it in this case. It's doing a lot of mixing of Java into the CF and isn't necessary beyond the demonstration.

ColdFusion: SQL Select IN from a Query

I have a SQL Server query which returns two values for one MyBusinessUnit column returns two values, say:
1111
2222
in a query object called MyQuery1
Both of these values also exist in a DB2 database's MyCorpUnit column.
What I want is to select all the matching records from the DB2 table--and, no, cross database queries are NOT working.
So, here's my Query2 for DB2 database:
<cfquery name="Query2" datasource="#application.DSN#">
SELECT MyCorpUnit WHERE MyCorpUnit IN
(
<cfqueryparam value=" #Query1.MyBusinessUnit #" CFSQLType="cf_sql_varchar" />
)
</cfquery>
But Query2 only returning matching record for only one value (1111).
So some other approach is needed. I have tried to create a string but that didn't work either.
Any idea?
Thanks!
cfqueryparam has a list attribute which might help:
<cfqueryparam value = "parameter value"
CFSQLType = "parameter type"
list = "yes|no"
maxLength = "maximum parameter length"
null = "yes|no"
scale = "number of decimal places"
separator = "separator character">
AND/OR ...additional criteria of the WHERE clause...>
I've used it before but not sure if it was in a QoQ or not. :D
ref: http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6f.html
I am going to accept #AJ Dyka answer [Thank you!] but I have more to add to make it complete. Indeed, per his advice, I ended up using the 'LIST' attribute. A good discussion on it can be found here.
But, as you can see in the comments, I was still getting only "1111" despite using a List. And that's because of the leading spaces in my data. I ended up using a TRIM function. Here is a code snippet.
Converted the output from Query1 to a List :
<cfset ListUniqueWStreamBusinessUnit = ValueList(Query1.MyBusinessUnit )>
Then the magical code snippet!
...
WHERE trim(GMMCU) IN
(
<cfqueryparam value="#ListUniqueWStreamBusinessUnit#"
CFSQLType="cf_sql_varchar"
list="yes" />
)

Perl: for (min .. max) uses random order, but I want it in order 0,1,2,

As I am a total beginner to perl, oracle sql and everything else. I have to write a script to parse an excel file and write the values into an oracle sql database.
Everything is good so far. But it writes the rows in random order into the database.
for ($row_min .. $row_max) {...insert into db code $sheetValues[$_][col0] etc...}
I don't get it why the rows are inserted in a random order?
And obviously how can I get them in order? excel_row 0 => db_row 0 and so on...
The values in the array are in order! The number of rows is dynamic.
Thanks for your help, I hope you got all the information you need.
Edit:
&parseWrite;
sub parseWrite {
my #sheetValues;
my $worksheet = $workbook->worksheet(0);
my ($row_min, $row_max) = $worksheet->row_range();
print "| Zeile $row_min bis $row_max |";
my ($col_min, $col_max) = $worksheet->col_range();
print " Spalte $col_min bis $col_max |<br>";
for my $row ($row_min .. $row_max) {
for my $col ($col_min .. $col_max) {
my $cell = $worksheet->get_cell ($row,$col);
next unless $cell;
$sheetValues[$row][$col] = $cell->value();
print $sheetValues[$row][$col] .
"(".$row."," .$col.")"."<br>";
}
}
for ($row_min .. $row_max) {
my $sql="INSERT INTO t_excel (
a,b,c,d,e
) VALUES (
'$sheetValues[$_][0 ]',
'$sheetValues[$_][1 ]',
'$sheetValues[$_][2 ]',
'$sheetValues[$_][3 ]',
'$sheetValues[$_][4 ]',
'$sheetValues[$_][5 ]'
)";
$dbh->do($sql);
}
}
With in order I mean that my PL/SQL Developer 8.0.3 (given by my company)
shows with SELECT * FROM t_excel;
pic
But shell = (2,0), maggie = (0,0) and 13 = (1,0) in the array.
The rows are being inserted in the order you expect. I believe the mistaken assumption here is that SELECT will return rows in the same order they're inserted. This is not true. While implementations may make it seem like it does, SELECT has no default order. You're thinking a table is basically like a big list, INSERT is adding to the end of it, and SELECT just iterates through it. That's not a bad approximation, but it can lead you to make bad assumptions. The reality is that you can say little for sure about how a table is stored.
SQL is a declarative language which means you tell the computer what you want. This is different from a most other language types where you tell the computer what to do. SELECT * FROM sometable says "give me all the rows and all their columns in the table". Since you didn't give an order, the database can return them in whatever order it likes. Contrast with the procedural meaning which would be "iterate through all the rows in the table" as if the table was some sort of list.
Most languages encourage you to take advantage of how data is stored. Declarative languages prevent you from knowing how data is stored.
If you want your SELECT to be ordered, you have to give it an ORDER BY.

sqlite select where...and vs. case...when

I'm new to sqlite and have a populated database where I need to determine if any of the digital organisms in the database have a threshold level of fitness (fitness>=2) and are alive (live=1). I also need to exclude the indivID (the Primary Key) of the organism for whom I am trying to find a fit mate (indivID INTEGER PRIMARY KEY).
Below I tried the first line of code but it threw a SQL error:
[SQLITE_ERROR] SQL error or missing database (near "CASE": syntax
error).
However I know the error is in the SQL statment because other functions are successfully accessing the database.
SELECT indivID FROM population CASE fitness >=2 WHEN live = 1 AND indivID!=[specific individual] ELSE NULL END
I have tried this next line of code, which works but does not properly exclude the indivID of the specific individual:
SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]
I have three questions:
1) Where are my errors in the above statements
2) What is the difference between using "case...when" and "where...and" statements
3) It is possible and even probable on these queries that there may not be a "live=1" individual with high enough fitness (above 2) to qualify for the select statement, so will the outcome of both of these queries with no viable individual (if correctly written) then be null?
Thanks in advance for your help!
According to your first query, you seem to misunderstand the usage of case when. It's like an if for a single value. It's usually used to get the required value based on some column values, e.g.
SELECT CASE WHEN col>0 THEN 1 ELSE 0 END FROM table
However it can also be used for some nifty tricks on the condition, e.g.
SELECT col FROM table WHERE CASE WHEN some_param = 1 THEN col2 = 1 ELSE true END
This statement retrieves column col for rows where col2 = 1 if some input parameter is 1 or for all rows if input parameter is something else than 1.
Using WHERE ... AND checks the condition, e.g.
SELECT col FROM table WHERE col>0 AND col2=0
In your case, you're trying to select a null if no matching values are found. I don't think it's the right way of dealing with it. You should attempt to select what you're looking for and then check whether you got any rows back. You would essentially get to something like this:
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]");
if(rs.first()) {
//You have some data - loop over the resultset and retrieve it
}
else {
//There are no matches to your query
}
If you only want one match, then you can simplify this to
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual] LIMIT 1");
String name = rs.first() ? rs.getString(1) : null;
Note that I used index 1 for getString - but it may be whatever you need.
EDIT: If you're dealing with SQLite, then you have a single-direction-moveable resultset, therefore you need to change the above code slightly:
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]");
if(!rs.isBeforeFirst()) {
//You have some data - loop over the resultset and retrieve it
}
else {
//There are no matches to your query
}
And, correspondingly,
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual] LIMIT 1");
String name = !rs.isBeforeFirst() ? null : rs.getString(1) : null;;
Note the change of rs.first() to !rs.isBeforeFirst() and the reversal of the condition.