I have to figure out a way whether a number (stored as string because of leading zeros) falls in a specific range. The ranges look like this:
12 - 14
3456 - 4567
1233435 would be considered to fall in the first range (matching is from the left).The number can have a maximum of 20 digits and I have a file which has all ranges included. I imported the ranges adding trailing zeros to the lower bound and trailing nines to the upper bound to reach the length of 20. This is to be able to handle variable length numbers - they are padded with zeros on the right so that I can do the following query:
SELECT * FROM ranges WHERE 'my padded number' BETWEEN bound_lower AND bound_upper
Since I have a couple of thousand ranges I would like to put an index on the table but I am not sure how I can achieve this.
Thanks,
Mendel
That seems like a valid approach that you've taken. To add the index, you just have to:
CREATE INDEX between_index on ranges (bound_lower, bound_upper);
You can verify that it is working by using EXPLAIN.
Related
I'm trying to run a formula to identify in which row a total sum is reached.
I've been able to do that calculation when I have an entire range of cells to work with, however, I'm doing a filter / join calculation because I need to do this from an individual row with all the data instead of an entire range of cells.
Here is an example google sheet (EDITABLE - feel free) where you can see the range and working formula (both below). Help getting this from the single-cell versions on the top would be very helpful. The error I get with both row() & index() formulas is that the "argument must be a range".
If there's another way to do this besides the single-cell I had that doesn't require referencing the range (e.g. using FILTER) then I'm open to it.
My desired result is to be able to pull the get the second column (date) at the point when the sum is reached (can be via the INDEX & MATCH formula I used or an alternative). This will tell me the earliest date that feeds into the desired sum.
Yes unfortunately you can't do that trick with SUMIFS to get a running total unless the column being totalled is an actual range.
The only approach I know is to multiply successive values by a triangular array like this:
1 0 0 ...
1 1 0 ...
1 1 1 ...
so you get just the sum of the first value, the first 2 values, then 3 values up to n.
This is the formula in F5:
=ArrayFormula(match(E14,mmult(IF(ROW(A1:INDEX(A1:ALL1000,COUNT(split(A5,",")),COUNT(split(A5,","))))>=
COLUMN(A1:INDEX(A1:ALL1000,COUNT(split(A5,",")),COUNT(split(A5,",")))),1,0),TRANSPOSE(SPLIT(A5,",")))))
And the formula in F6 is just
=to_date(INDEX(TRANSPOSE(SPLIT(B5,",")),F5,1))
EDIT
You might have guessed that the above formula was adapted from Excel, where you try to avoid volatile functions like Offset and Indirect.
I have realised since posting this answer that it could be improved in two ways:
(1) By using Offset or Indirect, thus avoiding the need to define a range of arbitrary size like A1:ALL1000
(2) By implying a 2D array by comparing a row and column vector, rather than actually defining a 2D array. This would give you something like this in F5:
=ArrayFormula(match(E14,mmult(IF(ROW(indirect("A1:"&address(COUNT(split(A5,",")),1)))>=
COLUMN(indirect("A1:"&address(1,COUNT(split(A5,","))))),1,0),TRANSPOSE(SPLIT(A5,",")))))
which could be further simplified to:
=ArrayFormula(match(E14,mmult(IF(ROW(indirect("A1:A"&COUNT(split(A5,","))))>=
COLUMN(indirect("A1:"&address(1,COUNT(split(A5,","))))),1,0),TRANSPOSE(SPLIT(A5,",")))))
I'm not sure if this is possible but I have a small MySql database that is used with a call screener app for my PBX.. I can add single numbers such as (555) 123-4567, however I would like to enter in entire blocks of numbers like (555) 123-???? so that any number calling from the numbers (555) 123-0000 through (555) 123-9999 would be selected in one entry. I know you can use wildcards in queries etc., but can they be used inside row or column fields?
I think that should work, if you reverse the parameters of like. So if you have a table with 'number masks' to match with (assuming some table and column names here), it could look like this:
select * from NumberMasks m where :CallerNumber like m.Mask
For clarity: :CallerNumber is the phone number of the caller. NumberMasks is just an assumed name for the table, where Mask would be the column containing the mask to match with in the form of (555) 123-???? as specified in the question.
I have a column of countries with 50 different values that I want to reduce to United States and Other.
Can someone help me with that?
Another example is Age which has 48 values that I'd like to reduce to only 4 like 1 to 18 = youth, 18-27 = starting, etc.
I've actually got about 5 columns that I want to reduce the values of. So would I need to repeat the process multiple times in KNIME or can I accomplish multiple column value replacements at once?
The latter on can easily be achieved with the Rule Engine
$Col0$ > 1 AND $Col0$ <18 => "youth"
For the First problem I'd use a String Replace (Dictionary).
I don't think you replace all at once but you can loop over columns.
For the second case I would use Numeric Binner:
For each column a number of intervals - known as bins - can be
defined. Each of these bins is given a unique name (for this column),
a defined range, and open or closed interval borders. They
automatically ensure that the ranges are defined in descending order
and that interval borders are consistent. In addition, each column is
either replaced with the binned, string-type column, or a new binned,
string-type column is appended.
I have a current db table called scores that has 2 columns user_score and approved_score which are both Integer.
After initial launch we have decided to make things more exact by add a decimal to a score. So instead of getting a 10 you could get a 10.40 or a 10.47 ect. I am just curious on:
Should I change it to a decimal or a float based on us needing 2
decimal points with trailing 0. So: $table-> decimal('user_score', 8,
2)->change();
Will that mess up data in there already? Like will a
score of 123 stay 123? We rank based on score so the higher the
better.
A float would be more appropriate in this case, it doesn't sound like you need a high number of precision points after the decimal place. The data should not be impacted by changing the column type, so long as your values are not currently larger than (8,2).
Also, updating your existing data if you kept the column as an integer would be trivial as all you would need to do is UPDATE column SET column=column*100.
i was trying to create a money related app in which users can choose their currency. Mysql datatype i tried is decimal(19,4). Now the problem is few currencies need three precisions and some need two
Eg:
oman rial needs three precisions. ie 1000 baisa = 1 omani rial. Hence my customers may enter 6.783 omani rial.
Where as my US customers will need only 2 precisions as 100 cents = 1 dollar and they may enter 5.50.
When i insert these two entries to my database using decimal(19,4), it is saved as 6.7830 and 5.5000 respectively.
Now the real pain is when i need to display their entrys as i dont want to display that extra 0 in omani rial entry and that 00 in US dollar. I also tried float but last digit gets rounded off at times.
Is there any mysql data type in which i can save exact entry as it is without any rounding off or extra zeros? If there is no such entry, how can i make it ppssible?
You can use VARCHAR to store exact representations, but I don't recommend that because it takes more bytes to store a number as a string. And any arithmetic you do on the value will convert it to a number anyway.
I recommend you use DECIMAL(19,4), and then format the value in application code, to display it with the appropriate digits. Every programming language has some function like printf() that allows you to control the output formatting, regardless of the value stored.