TSQL compare varchar in digit form - tsql

Basically i did some comparison in my tsql as below
IF ('500' > '400')
PRINT('NO PROBLEM')
ELSE
PRINT('Error')
So, in this situation, the comparison should be no problem
IF ('2500' > '400')
PRINT('NO PROBLEM')
ELSE
PRINT('Error')
However, when the situation above appeared, 'Error' will be print. Basically, the code will do the comparison base on the first character of the strings. Can anyone explain?
Extra Question:
If i insist to compare the strings without casting it into INT or DOUBLE. How can i do it?

When you compare varchar values, the comparison is lexicographical i.e. according to alphabetical order. Therefore, if you treat 2 numeric values as strings, they will be compared as strings too. That means you need to convert the strings back to a numeric type if you want to compare by numeric value.

The right way is to compare numerical values.
However, if you cannot convert to numerical values, then you must 'pad' the smallest varchar number with 0, so it gets to the length of the longest varchar number.
So you end up with something like this:
IF ('2500' > '0400')
PRINT('NO PROBLEM')
ELSE
PRINT('Error')
The specifics of 'padding' zeros can be done in many ways.

Related

PureScript - Convert a number to an integer?

PureScript contains a method in the Integer library fromNumber.
Here is an example of how it might be used:
myInteger = fromMaybe 0 (fromNumber myNumber)
However the docs provide this puzzling explanation:
Creates an Int from a Number value. The number must already be an integer and fall within the valid range of values for the Int type otherwise Nothing is returned.
Basically, your number must already be an Integer to convert it to an integer.
Assuming your number is not already an integer, a reasonable use case, how would you convert it to a number?
If it's not already an integer, there is no one true way of converting it to an integer. You could round to the nearest integer, round up, round down, do banker's rounding, or some sort of crazy conversion scheme of your own.
The Data.Int module offers several functions for different conversion strategies, such as floor, ceil, and round.

Concat postgresql tsvectos without position offset

Based on https://www.postgresql.org/docs/13/textsearch-features.html
tsvector || tsvector
The tsvector concatenation operator returns a vector which combines the lexemes and positional information of the two vectors given as arguments. Positions and weight labels are retained during the concatenation. Positions appearing in the right-hand vector are offset by the largest position mentioned in the left-hand vector, so that the result is nearly equivalent to the result of performing to_tsvector on the concatenation of the two original document strings. (The equivalence is not exact, because any stop-words removed from the end of the left-hand argument will not affect the result, whereas they would have affected the positions of the lexemes in the right-hand argument if textual concatenation were used.)
One advantage of using concatenation in the vector form, rather than concatenating text before applying to_tsvector, is that you can use different configurations to parse different sections of the document. Also, because the setweight function marks all lexemes of the given vector the same way, it is necessary to parse the text and do setweight before concatenating if you want to label different parts of the document with different weights.
Thus this query
select 'a:1 b:2'::tsvector || 'a:1 c:2 b:3'::tsvector;
will result in 'a':1,3 'b':2,5 'c':4
Please advice is there a way to merge several tsvectors while preserving original positions (something similar to this):
select concat_with_preserving('a:1 b:2'::tsvector, 'a:1 c:2 b:3'::tsvector);
so it is equal to 'a':1 'b':2,3 'c':2, eg same positions deduplicated and different positions are just merged (w/o offset).
Thanks!
Convert then to text, then concatenate them with spaces between, then convert them back.
(a::text || ' ' || b::text)::tsvector

Remove commas and decimal places from number field

I am trying to add two zero place holders in front of a field without changing the actual values involved. The field is an order number that is being pulled from MOMs. So right now that fields' formula is {cms.ORDERNO}.
When I try '00'+{cms.ORDERNO} the field displays 001,254.00. How can I remove the decimals and comma so it displays 001254?
The usual trick is to pad with plenty of extra digits on the left and then only take the six you really want from the right. This would handle any order number ranging from 1 to 999999.
right("000000" + totext({cms.ORDERNO}, "0"), 6)
When you don't specify a format string, as you tried, it uses default settings which usually come from Windows. By the way, if I recall correctly cstr() and totext() are equivalent for the most part but totext() has more options.
You should also be able to specify "000000" as the format string to produce the left-padded zeroes. Sadly I don't have Crystal Reports installed or I'd check it out for you to be sure. If this is the case then you probably don't need a formula if you just want to use the formatting options for the field on the canvas. If you do use a formula it's still simple.
totext({cms.ORDERNO}, "000000")
You definitely want to use the Replace formula a few times for this. The formula below converts ORDERNO into string, removes any commas and trailing decimal places, then adds the two zeroes at the beginning:
`00` + REPLACE(REPLACE(CSTR({cms.ORDERNO}),".00",""),",","")
So for example, if cms.ORDERNO is 1,254.00 the output from this formula would be 001254
I know this is older, but better solutions exists and I ran across this same issue. ToText has what you need built right in.
"00" + ToText({cms.ORDERNO}, 0, "")
From the Crystal Documentation:
ToText (x, y, z)
x is a Number or Currency value to be converted into a text string; it
can be a whole or fractional value.
y is a whole number indicating the number of decimal places to carry
the value in x to (This argument is optional.).
z is a single character text string indicating the character to be
used to separate thousands in x. Default is the character specified in
your International or Regional settings control panel. (This argument
is optional.)

Format Matlab data to only have digits after the decimal place

I used dlmwrite to output some data in the following form:
-1.7693255974E+00,-9.7742420654E-04, 2.1528647648E-04,-1.4866241234E+00
What I really want is the following format:
-.1769325597E+00, -.9774242065E-04, .2152864764E-04, -.1486624123E+00
A space is required before each number, followed by a sign, if the number is negative, and the number format is comma delimited, in exponential form to 10 significant digits.
Just in case Matlab is not able to write to this format (-.1769325597E+00), what is it called specifically so that I can research other means of solving my problem?
Although this feels morally wrong, one can use regular expressions to move the decimal point. This is what the function
myFormat = #(x) regexprep(sprintf('%.9e', 10*x), '(\d)\.', '\.$1');
does. The input value is multiplied by 10 prior to formatting, to account for the point being moved. Example: myFormat(-pi^7) returns -.3020293228e+04.
The above works for individual numbers. The following version is also able to format arrays, providing comma separators. The second regexprep removes the trailing comma.
myArrayFormat = #(x) regexprep(regexprep(sprintf('%.9e, ', 10*x), '(\d)\.', '\.$1'), ', $', '');
Example: myArrayFormat(1000*rand(1,5)-500) returned
-.2239749230e+03, .1797026769e+03, .1550980040e+03, -.3373882648e+03, -.3810023184e+03
For individual numbers, myArrayFormat works identically to myFormat.

How to fscanf a combination of float and string?

The data is like this
5.1,3.5,1.4,0.2,Iris-setosa
while I read it using this
data = fscanf(file, '%f,%f,%f,%f,%s');
and it turned out that data is an array of float rather than a combination of float and string. So how do I read this data from txt?
From the Matlab docs for fscanf:
Output Arguments A: An array. If the format includes:
Only numeric specifiers, A is numeric. ... Only character or
string specifiers (%c or %s), A is a character array. ... A
combination of numeric and character specifiers, A is numeric, of
class double. MATLAB converts each character to its numeric
equivalent. This conversion occurs even when the format explicitly
skips all numeric values (for example, a format of '%*d %s').
So your best bet is to read everything in as strings, and then convert the numeric strings to numeric values, using str2num or str2double or similar.
Alternatively, since you know there are 4 floating point values that really store a floating point value, and then the rest store the numeric ASCII values for the string, you can always split up your data and cast the part you know should be a string to char. Something like:
flt = data(1:4);
str = char(data(5:end));