I'am a newbie.. I'm sorry if my question is repost.. i want to ask how to get value front of decimal on mysql..
here my fiddle example
i try to use FORMAT on mysql
`SELECT FORMAT(desc,0) FROM table1`
the result is round.. in my case i dont want the result rounded.
i want the result is
1. 9
2. 9
3. 11
4. 11
sorry if i'm wrong.. thanks for help..
FLOOR it.
SELECT id, FLOOR(desc) FROM table1
This will remove the decimal places and return that whole number which you are looking for.
Result
9
9
11
11
Fiddle
You can Use FLOOR()
select id,FLOOR(decs) from table1
SQL FIDDLE
SEE HERE
you can also use ROUND to truncate decimal places
SELECT ROUND(#column_name,0,1)
OR
example select CAST(Round(MySum * 20.0 /100, 0) AS INT)
91 * 20 / 100 => 1820 / 100 => 18 (truncated from 18.20)
use round().. get all the data from your sql database then loop it
for example you have
$number = "1.00";
or
$number = 1.00;
then use round()
echo round($number);
the output is 1
Related
I have a field name "value" which contains 4 digits, 8 digits and 16 digits. How do I get only the four digits using mysql statement "SELECT" with where condition?
Here are the example.
value
1001
90812323
8928123458341235
0123
4521
84920192
7584
Getting only the "1001,0123,4521 and 7584".
Is this possible?
SELECT value FROM table WHERE LENGTH(value)=4;
SELECT * FROM tb WHERE char_length(value) = 4
check this link: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
I'm trying to get this output.
MDT 1
MDT 2
MDT 3
MDT 11
MDT 44
but, The values are ordered alphabetically, so 123 comes before 2.
example :
MDT 1
MDT 11
MDT 156
MDT 2
MDT 3
MDT 303
MDT 44
and so on.
I'm use this code, but it seem didn't work.
SELECT * FROM file ORDER BY ABS(ID) ASC
How can I solve this?
If your ID is always going to contain the prefix as MDT, then you can use this, to sort as per your requirement:
SELECT * FROM File
ORDER BY CAST(replace(ID, 'MDT ', '') AS UNSIGNED) ASC
SQLFiddle demo
Try that snippet
SELECT * FROM file ORDER BY ID + 0 ASC
Try Like this it will sort based on numeric :
select substr(id,4)*1 from file order by substr(id,4)*1
It will gives
1
2
3
11
44
...
If You want all fields try the below query ("substr(id,4)" or "substr(id,5)") based on your string length (ex: id= proj-001911 --> take SUBSTR( id, 6 ) *1) )
select * from file order by substr(id,4)*1
SELECT * FROM file
ORDER BY CONVERT(SUBSTRING(ID,5),UNSIGNED) ASC
SUBSTRING() will extract all characters after 'MDT ' and CONVERT() will change remaining substring to unsigned integer on which ORDER BY is performed
note SUBSTR() is a synonym for SUBSTRING().
I was searching it out too, but just while reading over here I got it striked in my head and found one solution that if that column is having only numbers as data then you need to make modification in database table and define that column as INT value type, then I am sure what you need will be done.
Eg. {SELECT * FROM file ORDER BY CONVERT(SUBSTRING(ID,5),UNSIGNED) ASC} in such case Convert is column and that needs to be defined as INT(5) will work.
I want to insert data in a table called accounts, and one of the fields gotta have a random number, starting with 11 and be 9 digits long, for example 112345673 or 119876543. Is this possible through SQL or I have to do this in PHP then insert there?
If you're inserting one row at a time...
--INSERT dbo.table(column1, random_column)
SELECT 'column1_value',
'11' + RIGHT(REPLACE(CONVERT(VARCHAR(12), RAND()), '.', ''), 3)
+ RIGHT(REPLACE(CONVERT(VARCHAR(12), RAND()), '.', ''), 4);
If this is part of a multirow SELECT, you will see the same number assigned to each row, so you'd need to randomize based on other data in each row (or using NEWID() as Conrad pointed out), e.g.
--INSERT dbo.table(column1, random_column)
SELECT name, '11' + RIGHT(1000000 + ABS(CONVERT(BIGINT,
CONVERT(VARBINARY(16), NEWID()))), 7)
FROM sys.all_objects;
(I've commented out the INSERT so you can test the result independently.)
This would give you an 11 digit random number. In case the random number is shorter than 9 digits, it is prefixed with zeroes, so the overall length is always 11:
select '11' + right('11000000000' +
cast(abs(convert(bigint,convert(varbinary(8),newid()))) as varchar(20)), 9)
Maybe this is overly simplistic, but 110000000 + (ABS(CHECKSUM(NEWID())) % 10000000) would be a very lightweight way to produce what you want.
So
ALTER TABLE mySchema.myTable ADD CONSTRAINT DF_myColumn
DEFAULT 110000000 + (ABS(CHECKSUM(NEWID())) % 10000000) FOR myColumn
Use PHP.
$randnum = "11".rand(1000000, 9999999);
Then just insert that in the query, and voila.
Possible but not great performance. Try this.
insert into table2(randomNumberColumn)
select convert(bigint,'11' + convert(varchar(100),convert(bigint,right(convert(varchar(100),abs(convert(int,convert(varbinary(16),newid())))),7)))) as a
from table1
One issue with this is it doesn't guarantee length of 11 digits. Sometimes it will be 10 due to the smallness of the number. Haven't really looked into how to fill in the extra 0 when Random Number Generator comes up with a small number.
I would try:
SELECT '11'+REPLACE(STR(RAND(),9,7),'0.','')
...or this slight variation...
SELECT '11'+RIGHT(STR(RAND(),9,7),7)
...whichever proves faster.
For the mysql "between" operator, is it necessary for the before and after value to be numerically in order?
like:
BETWEEN -10 AND 10
BETWEEN 10 AND -10
Will both of these work or just the first one?
Also, can I do:
WHERE thing<10 AND thing>-10
Will that work or do I have to use between?
Lastly, can I do:
WHERE -10<thing<10
?
BETWEEN -10 AND 10
This will match any value from -10 to 10, bounds included.
BETWEEN 10 AND -10
This will never match anything.
WHERE thing<10 AND thing>-10
This will match any value from -10 to 10, bounds excluded.
Also, if thing is a non-deterministic expression, it is evaluated once in case of BETWEEN and twice in case of double inequality:
SELECT COUNT(*)
FROM million_records
WHERE RAND() BETWEEN 0.6 AND 0.8;
will return a value around 200,000;
SELECT COUNT(*)
FROM million_records
WHERE RAND() >= 0.6 AND RAND() <= 0.8;
will return a value around 320,000
The min value must come before the max value. Also note that the end points are included, so BETWEEN is equivalent to:
WHERE thing>=-10 AND thing<=10
Please keep it to one question per post. Anyway:
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
BETWEEN min AND max, in that order.
from the link:
This is equivalent to the expression (min <= expr AND expr <= max) if
all the arguments are of the same type
The second alternative will also work, of course.
First question:
Will both of these work or just the first one?
yes,both of these work
Second question:
Will that work or do I have to use between?
it also valid but as you can see just empty result
Yes your between must be in order to return the excepted result.
Let's say you have a table with a row called mynumber that contains 10 rows :
MyNumber
--------
1
2
3
4
5
6
7
8
9
10
So
select * from thistable table where table.myNumber BETWEEN 1 and 5
will return
1
2
3
4
5
but
select * from thistable table where table.myNumber BETWEEN 5 and 1
return nothing.
Your 2nd question : yes it is the same thing. but beware in you example you will have to put <= and >= to be the same as between. if not, in our example, you would get
2
3
4
Hope it help
I've already seen such things work with integers :
WHERE -10
But it's better to avoid it. One reason is that it doesn't seem to work well with other types. And MySQL doesn't issue any warning.
I've tried it with datetime columns, and the result was wrong.
My request looked like this one:
SELECT *
FROM FACT__MODULATION_CONSTRAINTS constraints
WHERE constraints.START_VALIDITY<= now() < constraints.END_VALIDITY
The result was not as expected. I got twice as many results as the same request with two inequalities (which returned correct results). Only the 1st part of the expression evaluated correctly.
Ok, let's suppose we have members table. There is a field called, let's say, about_member. There will be a string like this 1-1-2-1-2 for everybody. Let's suppose member_1 has this string 1-1-2-2-1 and he searches who has the similar string or as much similar as possible. For example if member_2 has string 1-1-2-2-1 it will be 100% match, but if member_3 has string like this 2-1-1-2-1 it will be 60% match. And it has to be ordered by match percent. What is the most optimal way to do it with MYSQL and PHP? It's really hard to explain what I mean, but maybe you got it, if not, ask me. Thanks.
Edit: Please give me ideas without Levenshtein method. That answer will get bounty. Thanks. (bounty will be announced when I will be able to do that)
convert your number sequences to bit masks and use BIT_COUNT(column ^ search) as similarity function, ranged from 0 (= 100% match, strings are equal) to [bit length] (=0%, strings are completely different). To convert this similarity function to the percent value use
100 * (bit_length - similarity) / bit_length
For example, "1-1-2-2-1" becomes "00110" (assuming you have only two states), 2-1-1-2-1 is "10010", bit_count(00110 ^ 10010) = 2, bit-length = 5, and 100 * (5 - 2) / 5 = 60%.
Jawa posted this idea originally; here is my attempt.
^ is the XOR function. It compares 2 binary numbers bit-by-bit and returns 0 if both bits are the same, and 1 otherwise.
0 1 0 0 0 1 0 1 0 1 1 1 (number 1)
^ 0 1 1 1 0 1 0 1 1 0 1 1 (number 2)
= 0 0 1 1 0 0 0 0 1 1 0 0 (result)
How this applies to your problem:
// In binary...
1111 ^ 0111 = 1000 // (1 bit out of 4 didn't match: 75% match)
1111 ^ 0000 = 1111 // (4 bits out of 4 didn't match: 0% match)
// The same examples, except now in decimal...
15 ^ 7 = 8 (1000 in binary) // (1 bit out of 4 didn't match: 75% match)
15 ^ 0 = 15 (1111 in binary) // (4 bits out of 4 didn't match: 0% match)
How we can count these bits in MySQL:
BIT_COUNT(b'0111') = 3 // Bit count of binary '0111'
BIT_COUNT(7) = 3 // Bit count of decimal 7 (= 0111 in binary)
BIT_COUNT(b'1111' ^ b'0111') = 1 // (1 bit out of 4 didn't match: 75% match)
So to get the similarity...
// First we focus on calculating mismatch.
(BIT_COUNT(b'1111' ^ b'0111') / YOUR_TOTAL_BITS) = 0.25 (25% mismatch)
(BIT_COUNT(b'1111' ^ b'1111') / YOUR_TOTAL_BITS) = 0 (0% mismatch; 100% match)
// Now, getting the proportion of matched bits is easy
1 - (BIT_COUNT(b'1111' ^ b'0111') / YOUR_TOTAL_BITS) = 0.75 (75% match)
1 - (BIT_COUNT(b'1111' ^ b'1111') / YOUR_TOTAL_BITS) = 1.00 (100% match)
If we could just make your about_member field store data as bits (and be represented by an integer), we could do all of this easily! Instead of 1-2-1-1-1, use 0-1-0-0-0, but without the dashes.
Here's how PHP can help us:
bindec('01000') == 8;
bindec('00001') == 1;
decbin(8) == '01000';
decbin(1) == '00001';
And finally, here's the implementation:
// Setting a member's about_member property...
$about_member = '01100101';
$about_member_int = bindec($about_member);
$query = "INSERT INTO members (name,about_member) VALUES ($name,$about_member_int)";
// Getting matches...
$total_bits = 8; // The maximum length the member_about field can be (8 in this example)
$my_member_about = '00101100';
$my_member_about_int = bindec($my_member_about_int);
$query = "
SELECT
*,
(1 - (BIT_COUNT(member_about ^ $my_member_about_int) / $total_bits)) match
FROM members
ORDER BY match DESC
LIMIT 10";
This last query will have selected the 10 members most similar to me!
Now, to recap, in layman's terms,
We use binary because it makes things easier; the binary number is like a long line of light switches. We want to save our "light switch configuration" as well as find members that have the most similar configurations.
The ^ operator, given 2 light switch configurations, does a comparison for us. The result is again a series of switches; a switch will be ON if the 2 original switches were in different positions, and OFF if they were in the same position.
BIT_COUNT tells us how many switches are ON--giving us a count of how many switches were different. YOUR_TOTAL_BITS is the total number of switches.
But binary numbers are still just numbers... and so a string of 1's and 0's really just represents a number like 133 or 94. But it's a lot harder to visualize our "light switch configuration" if we use decimal numbers. That's where PHP's decbin and bindec come in.
Learn more about the binary numeral system.
Hope this helps!
The obvious solution is to look at the levenstein distance (there isn't an implementation built into mysql but there are other implementations accesible e.g. this one in pl/sql and some extensions), however as usual, the right way to solve the problem would be to have normalised the data properly in the first place.
One way to do this is to calculate the Levenshtein distance between your search string and the about_member fields for each member. Here's an implementation of the function as a MySQL stored function.
With that you can do:
SELECT name, LEVENSHTEIN(about_member, '1-1-2-1-2') AS diff
FROM members
ORDER BY diff ASC
The % of similarity is related to diff; if diff=0 then it's 100%, if diff is the size of the string (minus the amount of dashes), it's 0%.
Having read the clarification comments on the original question, the Levenshtein distance is not the answer you are looking for.
You are not trying to compute the smallest number of edits to change one string into another.
You are trying to compare one set of numbers with another set of numbers. What you are looking for is the minimum (weighted) sum of the differences between the two sets of numbers.
Place each answer in a separate column (Ans1, Ans2, Ans3, Ans4, .... )
Assume you are searching for similarities to 1-2-1-2.
SELECT UserName, Abs( Ans1 - 1 ) + Abs( Ans2 - 2 ) + Abs( Ans3 - 1 ) + Abs( Ans4 - 2) as Difference ORDER BY Difference ASC
Will list users by similarity to answers 1-2-1-2, assuming all questions are weighted evenly.
If you want to make certain answers more important, just multiply each of the terms by a weighting factor.
If the questions will always be yes/no and the number of answers is small enough that all the answers can be fitted into a single integer and all answers are equally weighted, then you could encode all the answers in a single column and use BIT_COUNT as suggested. This would be a faster and more space-efficient implementation.
I would go with the similar_text() PHP built-in. It seems to be exactly what you want:
$percent = 0;
similar_text($string1, $string2, $percent);
echo $percent;
It works as the question expects.
I would go with the Levenshtein distance approach, you can use it within MySQL or PHP.
If you don't have too many fields, you could create an index on the integer representation of about_member. Then you can find the 100% by an exact match on the about_member field, followed by the 80% matches by changing 1 bit, the 60% matches by changing 2 bits, and so on.
If you represent your answer patterns as bit sequences you can use the formula (100 * (bit_length - similarity) / bit_length).
Following the mentioned example, when we convert "1"s to bit off and "2"s to bit on "1-1-2-2-1" becomes 6 (as base-10, 00110 in binary) and "2-1-1-2-1" becomes 18 (10010b) etc.
Also, I think you should store the answers' bits to the least significant bits, but it doesn't matter as long as you are consistent that the answers of different members align.
Here's a sample script to be run against MySQL.
DROP TABLE IF EXISTS `test`;
CREATE TABLE `members` (
`id` VARCHAR(16) NOT NULL ,
`about_member` INT NOT NULL
) ENGINE = InnoDB;
INSERT INTO `members`
(`id`, `about_member`)
VALUES
('member_1', '6'),
('member_2', '18');
SELECT 100 * ( 5 - BIT_COUNT( about_member ^ (
SELECT about_member
FROM members
WHERE id = 'member_1' ) ) ) / 5
FROM members;
The magical 5 in the script is the number of answers (bit_length in the formula above). You should change it according to your situation, regardless of how many bits there are in the actual data type used, as BIT_COUNT doesn't know how many bytes you are using.
BIT_COUNT returns the number of bits set and is explained in MySQL manual. ^ is the binary XOR operator in MySQL.
Here the comparison of member_1's answers is compared with everybody's, including their own - which results as 100% match, naturally.