count of rows which are not divided by a number - mysql

I have a column like below.
Value
_____
48
48
39
96
50
I want to divide this with 48.
From the above 5 values, row 1,2,4 can be divided, but 3,5 not. I have to do this with SQL.
EG:
select count(*) from tbl where value/42
Result: 2

You are asking for the remainder when an integer is divided by 48. That has a specific name in mathematics, the modulo operation. This is actually a very interesting (to some people) part of number theory and group theory.
Most databases support the modulo operator or function via %. So the idea is:
select value
from t
where value % 48 = 0;
This might be:
where value mod 48 = 0
where mod(value, 48) = 0
depending on the database.
Another method is:
where floor(val / 48) * 48 = val

You can do that with a simple where clause
SELECT value FROM table WHERE value%48 = 0
The modulus operator returns the remainder for the division of the operands which in fact means we are checking if the numbers are divisible (remainder is zero when numbers are divisible)
So, if you are trying to count what’s not divisible then simple use below query
SELECT count(value) FROM table WHERE value%48 != 0

You can use modulus(%) to find the result. Check below query it will help you.
declare #tbl table (val int)
insert #tbl values(48),(48),(39),(96),(50)
select * from #tbl where val % 48 =0
Output
val
48
48
96

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;

Compare two Alphanumerical mysql columns (Find postcode district between range)

I have a mysql database that contains a range of postcode district ranges.
I am trying to find the row that matches the given district, in this example 'SY18'.
I have mysql query below, but it returns both the values in the table because the fields are alphanumeric.
SELECT rate FROM table WHERE district_from <= 'SY18' AND district_to >= 'SY18'
Table example
id district_from district_to rate
1 SY1 SY9 10
2 SY16 SY22 20
3 AL1 AL99 37
4 B1 B99 37
5 BB1 BB99 37
6 CB1 CB99 40
How do I return only correct results?
You can use SUBSTR to skip first characters of the string and then +0 to consider the value as a number. Example:
SELECT v
FROM
(SELECT 'SY1' v UNION SELECT 'SY16') t
WHERE SUBSTR(t.v, 3)+0 > 10
;
CREATE FUNCTION normalize_district (district VARCHAR(4))
RETURNS VARCHAR(4) DETERMINISTIC
RETURN CONCAT( TRIM(TRAILING CASE WHEN 0 + RIGHT(district, 2) > 0
THEN RIGHT(district, 2)
ELSE RIGHT(district, 1) END FROM district),
LPAD(CASE WHEN 0 + RIGHT(district, 2) > 0
THEN 0 + RIGHT(district, 2)
ELSE 0 + RIGHT(district, 1) END, 2, '0') );
and then
SELECT *
FROM district_to_test
LEFT JOIN rate ON normalize_district(district_to_test.district)
BETWEEN normalize_district(district_from)
AND normalize_district(district_to);
fiddle
0 + RIGHT(district, 2) > 0 in the function thecks does the last 2 symbols in district are digits.
If true then 2-digit number wil be extracted by RIGHT(), and the whole expression value will be above zero (you claim that there is no values like 'AA0' or 'AA00').
If false, and only one digit is present, then RIGHT() will give a substring which is started from a letter, and the value will be zero.
Based on this I divide the whole value to a prefix and numeric postfix, and add a zero to the numeric part making it 2-digit unconditionally. Such value can be used for direct string comparing by BETWEEN operator.
The goal of a function is to convert the value to 'AA00' format. For this purposes we must divide the whole value to textual and numeric parts and normalize (zero-pad) the latter one.
You may use any other dividing method. For example, you may check does the value contains two digits using LIKE '%\\d\\d'. Or backward, you may determine does the value contains two letters using LIKE '\\D\\D%'... these methods have relatively equal difficulty.

Natural Sorting SQL ORDER BY

Can anyone lend me a hand as to what I should append to my ORDER BY statement to sort these values naturally:
1
10
2
22
20405-109
20405-101
20404-100
X
Z
D
Ideally I'd like something along the lines of:
1
2
10
22
20404-100
20405-101
20405-109
D
X
Z
I'm currently using:
ORDER BY t.property, l.unit_number
where the values are l.unit_number
I've tried doing l.unit_number * 1 and l.unit_number + 0 but they haven't worked.
Should I be doing sort of ORDER conditional, such as Case When IsNumeric(l.unit_number)?
Thank you.
This will do it:
SELECT value
FROM Table1
ORDER BY value REGEXP '^[A-Za-z]+$'
,CAST(value as SIGNED INTEGER)
,CAST(REPLACE(value,'-','')AS SIGNED INTEGER)
,value
The 4 levels of the ORDER BY:
REGEXP assigns any alpha line a 1 and non-alphas a 0
SIGNED INT Sorts all of the numbers by the portion preceding the dash.
SIGNED INT after removing the dash sorts any of the items with the same value before the dash by the portion after the dash. Potentially could replace number 2, but wouldn't want to treat 90-1 the same as 9-01 should the case arise.
Sorts the letters alphabetically.
Demo: SQL Fiddle

mysql lookup match

I have a database column like this:
id
50
55
56
62
63
64
65
68
70
72
80
etc...
I want to iterate through the id column with the following formula to find if the result of the formula is an id number in the same column. I want to compute all the possible combinations of the set of basically 3 records in the id column.
First loop:
Does ((second_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
Per the formula, the first loop is
(55-50)*2.00(as an example of variable decimal) + 55 = 65. 65 is in the list => 65 is tagged with the 2 records which equal it
Second loop:
Does ((third_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
(56-50)*2.00(as an example of variable decimal) + 56 = 78. 78 is not in the list => 78 is not tagged
Third loop:
Does ((fourth_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
etc...
I want the results to show all the tagged records. A tagged record is the set of the 3 records where the third record is the result from the formula.
Anyone got any ideas? Is it possible in mysql?
Thank you
If I'm understanding your requirements properly, it sounds like you'd want to use a self-join on the table, e.g.
SELECT ...
FROM yourtable AS parent
LEFT JOIN yourtable AS child ON
FLOOR((parent.second_id_number - parent.first_id_number) * variable) + parent.second_id) = child.id
You could potentially carry something like this forward, which satisfies your first "loop"
select a.id as first_id_number
, b.id as second_id_number
, ((b.id - a.id) * 2) + b.id as third_id_number
from my_table as a
join my_table as b on a.id = (select max(id) from my_table where id < b.id)
where ((b.id - a.id) * 2) + b.id in (select id from my_table)
According to your description and test data, this would show 65 as "tagged" with first_id_number 50 and 62.
Warning: done on SQL Server using what I think is fairly standard syntax. I would understand if some would rather phrase this as a cross join with the select max... bit in the where clause rather than in the join predicate.

Determine the range category of a specified number

So I have a column with different numbers and wish to categorize them by range within 30 minute intervals. So 5 would be 0-30, 697 would be 690-720, and 169 would be 150-180. I was first thinking of doing a case statement, but it doesn't look like Access 2003 supports it. Is there perhaps some sort of algorithm that could determine the range? Preferably, this would be done within the query.
Thank you.
Take the integer portion of (number / 30) using the Int function and multiply it by 30 to get your lower bound, then add 30 to that number to get your upper bound.
Examples
Int(5 / 30) = 0 * 30 = 0
Int(697 / 30) = 23 * 30 = 690
Use / (integer division) and * (multiplication).
5/30*30 = 0
697/30*30 = 690
169/30*30 = 150
...
Let x be your column with the values you want to catalogue, the in pseudo-SQL you have:
select ((x/30)*30) as minrange,
(((x/30)+1)*30) as maxrange
from yourtable
(you should take the integer part of the division).
Hope this helps.
This is fairly straight forward. You can just use the following.
(number \ 30) * 30
This will give you the lower index of your range. It does have one problem, which is that 30, 720, 180 etc, will be returned as themselves. This means your ranges either need to be 0-29, 690-719, etc, or have your caller take this into account.
This assumes you are using VBA where the '\' operator returns only the quotient. See more on VB operators here