In SQL Server 2008 I am trying to get results to truncate to a specific number of decimal places depending on the value of the field. The trouble I am running into is if the last decimal place is going to be zero then it doesn't display it. My code is as follows:
case when #field >= 250 then round(#field,1,1)
when #field between 100 and 249.9999 then round(#field,2,1)
when #field < 100 then round(#field,3,2) end
It works great by changing 250.36745 into 250.3, but 250.04567 returns 250 and I need it to be 250.0
The result given back to you depends on the original data type for #field. I'd assume that you haven't chosen a precise data type (example: float) for #field and therefore get a variable result back. If you want a precise result back then you can do so by wrapping your case statement into a cast like so:
cast(case when #field >= 250 then round(#field, 1, 1)
when #field between 100 and 249.9999
then round(#field, 2, 1)
when #field < 100 then round(#field, 3, 2)
end as decimal(19, 1))
If you still feel that you allegedly get back 250 instead of 250.0 from the server then I'd question the front-end tool you are using to execute the query and to display the result. In SSMS you will certainly get back 250.0. But if you are using a different client then the result may vary.
Related
I have in project array of workout programs (code for them are on Objective-C) and in every program I have #property (nullable, nonatomic, copy) NSString *scheduleStr; for program durations. This property stores values such as 1 week, 2 weeks, 3 weeks and etc. I need to filter all values bigger than 6 weeks. I'm trying to apply NSPredicate:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 6"))
and after this I'm receiving only programs with length 6-9 weeks, but nothing more than 10 weeks, but for sure I have several programs in database with length equal 12 weeks.
If I'm trying to apply something like this:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 10"))
I will receive almost all the programs. How to get all programs with more than selected values?
The problem is that, although you specify integerValue, when using the predicate as part of a fetch, CoreData treats your string as a string. In string terms, 10 weeks is "less than" 6 weeks, so it's excluded from the results.
You should store the number (as an Int) instead of storing the string. Adding the text " weeks" is then something you do for display purposes. If you store the number, rather than the string, then CoreData can do a numerical comparison and your predicate will work as you expect.
If you really don't want to do that, there is one workaround, and one hack. The workaround is to filter the objects in memory rather than as part of a fetch. The integerValue will then be correctly interpreted and the comparison will be numerical.
The hack is to force CoreData to treat your string as though it is a number, by using a numeric function, like abs (assuming you only have a positive number of weeks, taking the absolute value leaves the value unchanged):
predicates.append(NSPredicate(format: "abs:(scheduleStr) >= 6"))
To get the integer part in the string in your case you can look into something like:
Suppose element is your string then
let component = element.components(separatedBy: .letters) // this will give you the non letter values
let integerValues = component.filter({ $0 != "" })
print(integerValues[0]) // As first value in your input string is an integer
This will give you the integer part of the string which can be used to filter the array.
Note, I'm aware of OrientDB geolocation (though I have some trouble with the poor formatting of the accepted answer, as it makes huge assumptions and in fact may be syntactically incorrect, but cannot yet submit edits).
I have a Vertex of Bank with a property of latLong as a comma-delimited string. I'm having some trouble using the provided distance() function with OrientDB. Since distance(x,y,lat,long) is expecting discrete values we wrote a split function that returns the latLong as an array:
{ ..., values: [xx.xxx,yy.yyy], ... }
However, I (we) can't seem to make either the provided answer or the document example to work. I suspect the answer is simple and we're over thinking it, but we're stuck.
split(input,delimiter)
return input.split(delimiter)`
Pretty simple really.
What's wrong in the original question?
In the cited question above, the query
select distance(x,y,originx,originy) <= 30 as distance from Bank order by distance
generates the below error
com.orientechnologies.orient.core.sql.OCommandSQLParsingException: Error on parsing command at position #0: Error parsing query: select distance(x,y,originx,originy) <= 30 as distance from Bank Encountered " "<=" "<= ""
and should be
select distance(x,y,lat,long) as distance from Bank where distance <= 30 order by distance;
which returns nothing.
If Bank were to have discrete properties for lat and long, how are they passed to distance()? Specifically, is OrientDB expecting specific property names?
You have to insert in Bank the properties lat and long like double
I am writing a very small URL shortener with Dancer. It uses the REST plugin to store a posted URL in a database with a six character string which is used by the user to access the shorted URL.
Now I am a bit unsure about my random string generation method.
sub generate_random_string{
my $length_of_randomstring = shift; # the length of
# the random string to generate
my #chars=('a'..'z','A'..'Z','0'..'9','_');
my $random_string;
for(1..$length_of_randomstring){
# rand #chars will generate a random
# number between 0 and scalar #chars
$random_string.=$chars[rand #chars];
}
# Start over if the string is already in the Database
generate_random_string(6) if database->quick_select('urls', { shortcut => $random_string });
return $random_string;
}
This generates a six char string and calls the function recursively if the generated string is already in the DB. I know there are 63^6 possible strings but this will take some time if the database gathers more entries. And maybe it will become a nearly infinite recursion, which I want to prevent.
Are there ways to generate unique random strings, which prevent recursion?
Thanks in advance
We don't really need to be hand-wavy about how many iterations (or recursions) of your function there will be. I believe at every invocation, the expected number of iterations is geomtrically distributed (i.e. number of trials before first success is governed by the geomtric distribution), which has mean 1/p, where p is the probability of successfully finding an unused string. I believe that p is just 1 - n/63^6, where n is the number of currently stored strings. Therefore, I think that you will need to have stored 30 billion strings (~63^6/2) in your database before your function recurses on average more than 2 times per call (p = .5).
Furthermore, the variance of the geomtric distribution is 1-p/p^2, so even at 30 billion entries, one standard deviation is just sqrt(2). Therefore I expect ~99% of the time that the loop will take fewerer than 2 + 2*sqrt(2) interations or ~ 5 iterations. In other words, I would just not worry too much about it.
From an academic stance this seems like an interesting program to work on. But if you're on the clock and just need random and distinct strings I'd go with the Data::GUID module.
use strict;
use warnings;
use Data::GUID qw( guid_string );
my $guid = guid_string();
Getting rid of recursion is easy; turn your recursive call into a do-while loop. For instance, split your function into two; the "main" one and a helper. The "main" one simply calls the helper and queries the database to ensure it's unique. Assuming generate_random_string2 is the helper, here's a skeleton:
do {
$string = generate_random_string2(6);
} while (database->quick_select(...));
As for limiting the number of iterations before getting a valid string, what about just saving the last generated string and always building your new string as a function of that?
For example, when you start off, you have no strings, so let's just say your string is 'a'. Then the next time you build a string, you get the last built string ('a') and apply a transformation on it, for instance incrementing the last character. This gives you 'b'. and so on. Eventually you get to the highest character you care for (say 'z') at which point you append an 'a' to get 'za', and repeat.
Now there is no database, just one persistent value that you use to generate the next value. Of course if you want truly random strings, you will have to make the algorithm more sophisticated, but the basic principle is the same:
Your current value is a function of the last stored value.
When you generate a new value, you store it.
Ensure your generation will produce a unique value (one that did not occur before).
I've got one more idea based on using MySQL.
create table string (
string_id int(10) not null auto_increment,
string varchar(6) not null default '',
primary key(string_id)
);
insert into string set string='';
update string
set string = lpad( hex( last_insert_id() ), 6, uuid() )
where string_id = last_insert_id();
select string from string
where string_id = last_insert_id();
This gives you an incremental hex value which is left padded with non-zero junk.
My language has certain keywords which only accept values of certain length range (say, between 5 and 10 decimal numbers). This id correct:
KeyWord = 01234
This is incorrect:
KeyWord = 1234
I have a rule;
KeyWord:
'KeyWord' '=' INT+;
How to limit the number of times INT can repeat? This would so much easier if it was a more regexp-like syntax
I would implement this as a validation check instead of trying to fit this in the grammar itself. See http://www.eclipse.org/Xtext/documentation/2_1_0/050-validation.php
This will result in better error recovery and better error messages. It even allows quick-fixes.
I want to print a simple statement
print (1=1), i expect the result to be TRUE or 1 but sql server tell me:
Incorrect syntax near '='.
why is that?
Same will happen for a statement like that
declare #test bit
set #test = (1=1)
in summary how can i "see" what is returned from a comparison without using an IF statement
Update: The reason i'm asking is because i'm trying to debug why the following statement
declare #AgingAmount smallint
set #AgingAmount = 500
select Amount, datediff(day,Batch.SubmitDate,getdate()) as Aging from myreporrt
where datediff(day,Batch.SubmitDate,getdate()) > #AgingAmount
will return all rows even with aging of 300
so i wanted to test if datediff(day,datesubmited,getdate()) > 500 returns true or false but could not find a way how to display the result of this comparison.
Although SQL Server has the concept of aboolean type, and it understands expressions that resolve to a boolean in IF and WHERE clauses, it does not support declaring boolean variables or parameters. The bit data type cannot store the result of a boolean expression directly, even though it looks suspiciously like one.
The nearest you can get to a boolean data type is this:
-- Store the result of a boolean test.
declare #result bit
select #result = case when <boolean expression> then 1 else 0 end
-- Make use of the above result somewhere else.
if #result = 1
...
else
...
To add to the confusion, SQL Server Management Studio treats bit like boolean when displaying results, and ADO.NET maps bit to System.Boolean when passing data back and forth.
Update: To answer your latest question, use the case when ... then 1 else 0 end syntax in the select statement.