Why we use in & in mysql query condition? - mysql

One of guys share me a query but still i am not undestand what is mean. Any one have idea why we use "&" in mysql query.
It also return result but don't know what condition is applying.

It is a bitwise logical AND operator.

The operator & is the bitwise AND operator for MySql.
...why we are use "&" in for condition
Your question is application specific and can't be answered without knowing the requirement.
The binary representation of 30 is 00011110.
As you can see this number has the bits 2 to 5 (starting from right) set (=1).
Any integer number, like entity_id, when written in binary, that has any of these bits set when used in the operation entity_id & 30 would return a non-zero value.
For example when entity_id = 12, then entity_id in binary is 00001100 and:
00001100(=12) & 00011110(=30) = 00001100(=12)
which is non-zero value interpreted as TRUE in the WHERE clause.
But when entity_id = 129, then entity_id in binary is 10000001 and:
10000001(=129) & 00011110(=30) = 00000000(=0)
which is 0 and it is interpreted as FALSE in the WHERE clause.
So, entity_id = 12 will be returned by the query but entity_id = 129 will be filtered out.

& is bitwise and operator
please be aware that this condition is terribly wrong when you're looking for exact 30 for id, for example it will match 62 and 2, 4, 6, ... also (any integer that has common 1 in the 5 least-significant digits with 11110 (30 in binary) in it's binary form)

Related

In SQL - how can I count the number of times Bit(0), Bit(1), ... Bit(N) are high for a decimal number?

I am dealing with a table of decimal values that represent binary numbers. My goal is to count the number of times Bit(0), Bit(1),... Bit(n) are high.
For example, if a table entry is 5 this converts to '101' which can be done using the BIN() function.
What I would like to do is increment a variable 'bit0Count' and 'bit2Count'
I have looked into the BIT_COUNT() function however this would only return 2 for the above example.
Any insight would be greatly appreciated.
SELECT SUM(n & (1<<2) > 0) AS bit2Count FROM ...
The & operator is a bitwise AND.
1<<2 is a number with only 1 bit set, left-shifted by two places, so it is binary 100. Using bitwise AND against you column n is either binary 100 or binary 000.
Testing that with > 0 returns either 1 or 0, since in MySQL, boolean results are literally the integers 1 for true and 0 for false (note this is not standard in other implementations of SQL).
Then you can SUM() these 1's and 0's to get a count of the occurrences where the bit was set.
To tell if bit N is set, use 1 << N to create a mask for that bit and then use bitwise AND to test it. So (column & (1 << N)) != 0 will be 1 if bit N is set, 0 if it's not set.
To total these across rows, use the SUM() aggregation function.
If you need to do this frequently, you could define a stored function:
CREATE FUNCTION bit_set(UNSIGNED INT val, TINYINT which) DETERMINISTIC
RETURN (val & (1 << which)) != 0;

MySQL possible bug

Imagine you have a table with 50000 rows and want to delete 5 entries based on the PK value. The expected query might look like this:
DELETE FROM table_name WHERE id = 5 OR id = 10 OR id = 15 OR id = 20 OR id = 25
This works as expected. However, if you're in a hurry and accidentally format it like this:
DELETE FROM table_name WHERE id = 5 OR 10 OR 15 OR 20 OR 25
It will delete all 50000 rows. Does anyone know if this is a bug? If not I don't understand why it treats it like a delete all instead of return a syntax error.
That is not a bug in MySQL.
10, 15, 20 and 25 are truthy values. So when the OR is evaluated against one of them, the whole condition is true.
You should consider an IN clause.
In MySQL, unlike standard SQL:
false and the integer 0 are treated the same
true and the integer 1 are treated the same
any integer value other than zero is also treated as true
See https://dev.mysql.com/doc/refman/8.0/en/boolean-literals.html
Your expression is combining several terms as boolean conditions:
(id = 5) OR (10) OR (15) OR (20) OR (25)
Since all non-zero integers are treated as true, this ends up being like:
(id = 5) OR (true) OR (true) OR (true) OR (true)
And you should recall from high school math that X OR true evaluates as true.
Note that the your expression would also do something you don't expect in many other programming languages. Using integer as a series of boolean terms doesn't compare those integers to the operand of the first term.

How do I Query for used BETWEEN Operater for text searches in MySql database?

I have a SQL Table in that i use BETWEEN Operater.
The BETWEEN Operater selects values within range. The values can be numbers, text , dates.
stu_id name city pin
1 Raj Ranchi 123456
2 sonu Delhi 652345
3 ANU KOLKATA 879845
4 K.K's Company Delhi 345546
5 J.K's Company Delhi 123456
I have a query like this:-
SELECT * FROM student WHERE stu_id BETWEEN 2 AND 4 //including 2 & 4
SELECT * FROM `student` WHERE name between 'A' and 'K' //including A & not K
Here My Question is why not including K.
but I want K also in searches.
Don't use between -- until you really understand it. That is just general advice. BETWEEN is inclusive, so your second query is equivalent to:
WHERE name >= 'A' AND
name <= 'K'
Because of the equality, 'K' is included in the result set. However, names longer than one character and starting with 'K' are not -- "Ka" for instance.
Instead, be explicit:
WHERE name >= 'A' AND
name < 'L'
Of course, BETWEEN can be useful. However, it is useful for discrete values, such as integers. It is a bit dangerous with numbers with decimals, strings, and date/time values. That is why I encourage you to express the logic as inequalities.
In supplement to gordon's answer, one way to get what you're expecting is to turn your name into a discrete set of values:
SELECT * FROM `student` WHERE LEFT(name, 1) between 'A' and 'K'
You need to appreciate that K.K's Company is alphabetically AFTER the letter K on its own so it is not BETWEEN, in the same way that 4.1 is not BETWEEN 2 and 4
By stripping it down to just a single character from the start of the string it will work like you expect, but take cautionary note, you should always avoid running functions on values in tables, because if you had a million names, thats a million strings that mysql has to strip out to just the first letter and it might no longer be able to use an index on name, battering the performance.
Instead, you could :
SELECT * FROM `student` WHERE name >= 'A' and name < 'L'
which is more likely to permit the use of an index as you aren't manipulating the stored values before comparing them
This works because it asks for everything up to but not including L.. Which includes all of your names starting with K, even kzzzzzzzz. Numerically it is equivalent to saying number >= 2 and number < 5 which gives you all the numbers starting with 2, 3 or 4 (like the 4.1 from before) but not the 5
Remember that BETWEEN is inclusive at both ends. Always revert to a pattern of a >= b and a < c, a >= c and a < d when you want to specify ranges that capture all possible values
Compare in lexicographical order, 'K.K's Company' > 'K'
We should convert the string to integer. You can try that mysql script with CAST and SUBSTRING. I've updated your script here. It will include the last record as well.
SELECT * FROM student WHERE name CAST(SUBSTRING(username FROM 1) AS UNSIGNED)
BETWEEN 'A' AND 'K';
The script will work. Hope it will helps to you.
Here I've attached my test sample.

How to exclude non-numeric column results from MySQL query?

I have a column, called value, that includes strings as well as numbers as data, eg:
contentid, value
16, 200
18, 150
47, Foo
16, Red
16, 50
18, GREEN
I need a way to retrieve only the results that are actual numbers (and, additionally, that are <= 180).
The expected results from above should be: 18, 150 and 16, 50 but I am getting results with strings as well.
I have tried this from other SO questions:
SELECT *
FROM `contentvalues`
WHERE (
contentid =16
OR contentid =18
)
AND `value` <= 180
AND value NOT LIKE '%[a-z0-9]%'
But this has not worked.
Would anyone be able to point me in the right direction?
According to this:
... AND value REGEXP ('[0-9]')
... but someone's blog is never the best source. Actually that matches everything that contains a number. Better would be
... AND value REGEXP ('^[0-9]+$')
Above regex is
^ "From the begining of the string..."
[0-9] "There should be a number..."
+ "actually exactly 1 or more of those numbers"
$ "and the the string should just end."
Here is a solution which does not require the REGEXP() function, which may not available in all RDBMS:
SELECT *
FROM `contentvalues`
WHERE (contentid = 16 OR contentid =18)
AND concat('',value * 1) = value
This will work as long as the numbers in the value column do not appear in scientific notation, with trailing decimals, or other weird formats. Read this SO article for more information.

MySQL: compare a mixed field containing letters and numbers

I have a field in the mysql database that contains data like the following:
Q16
Q32
L16
Q4
L32
L64
Q64
Q8
L1
L4
Q1
And so forth. What I'm trying to do is pull out, let's say, all the values that start with Q which is easy:
field_name LIKE 'Q%'
But then I want to filter let's say all the values that have a number higher than 32. As a result I'm supposed to get only 'Q64', however, I also get Q4, Q8 and so for as I'm comparing them as strings so only 3 and the respective digit are compared and the numbers are in general taken as single digits, not as integers.
As this makes perfect sense, I'm struggling to find a solution on how to perform this operation without pulling all the data out of the database, stripping out the Qs and parsing it all to integers.
I did play around with the CAST operator, however, it only works if the value is stored as string AND it contains only digits. The parsing fails if there's another character in there..
Extract the number from the string and cast it to a number with *1 or cast
select * from your_table
where substring(field_name, 1, 1) = 'Q'
and substring(field_name, 2) * 1 > 32