Finding values between 2 table columns - mysql

My Table structure is like this
-------------------------------------
| from | to | price | pid | type|
| 0 | 100 | 50 | 2 | new |
| 101 | 200 | 60 | 2 | new |
| 201 | 300 | 70 | 2 | new |
| 301 | 700 | 80 | 2 | new |
| 301 | 700 | 70 | 2 | old |
Now i am getting a value from that i have to get the price.
Let say my value is 106 then i should get the price 60.
My query is
SELECT * FROM tbl_goals WHERE from <= '106' AND to >='106' AND pid='2' AND type='new'
With this query i am getting all rows with type new
But in result i should get this row
| 101 | 200 | 60 | 2 | new |
Where i am doing wrong?

I would use BETWEEN here for the sake of readability:
SELECT *
FROM tbl_goals
WHERE 106 BETWEEN `from` AND `to` AND
pid = 2 AND
type = 'new'
Notes:
Don't put single quotes around numbers in your query when you want to treat them as numbers
Don't names your columns from or any other MySQL keyword, because then you might have to escape them everywhere in backticks to make the query work as intended

Related

Precalculate numbers of records for each possible combination

I have a mySQL database table containing cellphones information like this:
ID Brand Model Price Type Size
==== ===== ===== ===== ====== ====
1 Apple A71 3128 A 40
2 Samsung B7C 3128 B 20
3 Apple ZX5 3128 A 30
4 Huawei Q32 2574 B 40
5 Apple A21 2574 A 25
6 Apple A71 3369 A 30
7 Samsung A71 7413 C 40
Now I want to create another table, that would contain counts for every possible combination of the parameters.
Params Count
============================================== =======
ALL 1000000
Brand(Apple) 20000
Brand(Apple,Samsung) 40000
Brand(Apple),Model(A71) 7100
Brand(Apple),Type(A) 6000
Brand(Apple),Model(A71,B7C),Type(A,B) 7
Model(A71) 12514
Model(A71,B7C) 26584
Model(A71),Type(A) 6521
Model(A71),Type(A,B) 8958
Model(A71),Type(A,B),Size(40) 85
And so on for every possible combination. I was thinking about creating a stored procedure (that i would execute periodically), that would perform queries with every existing condition like that, but I am a little stuck on how exactly should it look like. Or is there a better way how to do this?
Edit: the reason why I want to store information like this is to be able to show number of results in filter in client application, like in the picture.
I would like to create index on the Params column to be able to get the Count number for given hash instantly, improving performance.
I also tried querying and caching the values dynamically, but I want to try this approach as well, so I can compare which one is more effective.
This is how I am calculating the counts now:
SELECT COUNT(*) FROM products;
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple', 'Samsung');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple') AND Model IN ('A71');
etc.
You can use a ROLLUP for this.
SELECT
model, type, size, COUNT(*)
FROM mytab
GROUP BY 1, 2, 3
WITH ROLLUP
With your sample data, we get the following:
| model | type | size | COUNT(*) |
| ----- | ---- | ---- | -------- |
| A21 | A | 25 | 1 |
| A21 | A | | 1 |
| A21 | | | 1 |
| A71 | A | 30 | 1 |
| A71 | A | 40 | 1 |
| A71 | A | | 2 |
| A71 | C | 40 | 1 |
| A71 | C | | 1 |
| A71 | | | 3 |
| B7C | B | 20 | 1 |
| B7C | B | | 1 |
| B7C | | | 1 |
| Q32 | B | 40 | 1 |
| Q32 | B | | 1 |
| Q32 | | | 1 |
| ZX5 | A | 30 | 1 |
| ZX5 | A | | 1 |
| ZX5 | | | 1 |
| | | | 7 |
The subtotals are present in the rows with null values in different columns, and the total is the last row where all group by columns are null.

MySQL, Insert Row in-between two others

I'm coding a website for a photographer and I'm currently working on gallery implimentation.
I need to be able to take a row from point n.a and move it to point n.b
Here's an example of the raw table:
|gallery_img |
|--------------------------|
| id | fk_gal | fk_img | o |
| | | | |
| 0 | 16 | 240 | 1 |
| 1 | 16 | 322 | 2 |
| 2 | 27 | 240 | 1 |
| 3 | 16 | 245 | 3 |
| 4 | 16 | 210 | 4 |
| 5 | 27 | 530 | 2 |
All fields are INT(11). 'id' Auto_increments. 'fk_gal' and 'fk_img' are linked to other, irrelevant, tables via FOREIGN_KEY.
Now, 'o' is the field I'm focusing on. It determines what order the images will be displayed on the website. This value needs to always be unique for each table. To clarify, If I only call one table, 'o' should be different in every row. However, if I call the entire table, 'o[0]' might reoccur a few times.
So here's what I need. Firstly, I'm only going to be running this function on only one gallery at a time so all visuals of the table from here on out are going to be filtered with 'SELECT * FROM gallery_img WHERE fk_gal = 16'.
I need to change 'o' from n to n2 which will effectively move it on the database.
|gallery_img |
|--------------------------|
| id | fk_gal | fk_img | o |
| | | | |
| 0 | 16 | 240 | 1 |
| | | | | <--
| 1 | 16 | 322 | 2 |+ |
| 3 | 16 | 245 | 3 |+ |
| 4 | 16 | 210 | 4 | --|
The code needs to move the desired row (in this example 'o=4') to 1 and simultaneously move all of the next rows down to prevent any reoccurrences.
Here's my code I have right now. I'm coding my MySql scripts via PHP.
I am using the $n variable here. It includes the following data:
$n = array(gallery_id,img_id,target_o);
sql("UPDATE gallery_img SET o = o + 1 ORDER BY o ASC LIMIT ". ($n[2] - 1) .", 18446744073709551615;");
sql("UPDATE gallery_img SET o = ". ($n[2] + 2) ." WHERE fk_img = $n[1] AND fk_gal = $n[0];");
The problem I'm having with this is that when I execute it I get one of these two outputs:
|gallery_img |
|--------------------------|
| id | fk_gal | fk_img | o |
| | | | |
| 0 | 16 | 240 | 1 |
| 4 | 16 | 210 | 1 | <-- Shouldn't be duplicate
| 1 | 16 | 322 | 2 |
| 3 | 16 | 245 | 3 |
|gallery_img |
|--------------------------|
| id | fk_gal | fk_img | o |
| | | | |
| 0 | 16 | 240 | 1 |
| 4 | 16 | 210 | 2 |
| 1 | 16 | 322 | 4 |-|
| 3 | 16 | 245 | 4 | |-- Shouldn't be duplicate
| 5 | 16 | 273 | 4 | |
| 6 | 16 | 14 | 4 |-|
A good way to think of it is as so:
UPDATE
If you have any questions please let me know!
Thanks ahead of time for your help!
So if you're wanting to change the row WHERE o=4 to o=1 then increment the number to be replaced and all greater numbers.
UPDATE gallery_img SET o = (o + 1) WHERE o >= 1
Then update the row that you want to be o=1:
UPDATE gallery_img SET o = 1 WHERE fk_img = something1 AND fk_gal = something2
Or if you only know the o use o=(4+1) since it changed in the last UPDATE:
UPDATE gallery_img SET o = 1 WHERE o = 5
Can I suggest a hack? For the column o don't use an integer number, but a DOUBLE PRECISION one.
It would be much easier to insert a row in between, just by averaging the values of the previous and next row. If you need to insert between 3 and 4, you can just insert a row with 3.5.
Of course, after some time (after 50 times at least) you would like to re-number those values, since a DOUBLE PRECISION has 53 bits for the mantissa.

Is it possible to create calculation rows from query results in MySQL?

I am trying to find a way to output a calculation row (or two) of an SQL search query, so I may see the raw results along with a calculation associated to them, either above or under the listing of raw results. For instance, I have the following data:
mysql> select * from data [where condition];
+----+--------+-----+--------+
| id | height | age | weight |
+----+--------+-----+--------+
| 1 | 65.2 | 45 | 45.23 |
| 2 | 63.1 | 47 | 0 |
| 3 | 59.2 | 37 | 38.1 |
| 4 | 59.8 | 39 | 36.4 |
| 5 | 63.4 | 37 | 38.1 |
| 6 | 72.1 | 34 | 2 |
| 7 | 100 | 50 | 20 |
+----+--------+-----+--------+
And what I want is to be able to perform any query to get all or a subset of this data, but have the resulting table give something like the following (with the summary/calculation output separate from the raw data, such as either above or below it):
mysql> query???
+--------+--------+------+--------+
| id | height | age | weight |
+--------+--------+------+--------+
| 1 | 65.2 | 45 | 45.23 |
| 2 | 63.1 | 47 | 0 |
| 3 | 59.2 | 37 | 38.1 |
| 4 | 59.8 | 39 | 36.4 |
| 5 | 63.4 | 37 | 38.1 |
| 6 | 72.1 | 34 | 2 |
| 7 | 100 | 50 | 20 |
+--------+--------+------+--------+
| STDDEV | 13.26 | 5.57 | 17.15 |
| COUNT | 7 | 7 | 7 |
| etc. | etc. | etc. | etc. |
+--------+--------+------+--------+
I've found some approaches such as this (http://www.sqlservercurry.com/2011/06/sql-server-row-summary-column-summary.html) that somewhat do it, but because the calculation acts on all rows it doesn't work well for some calculations (for instance, using stddev results in "0" for everything except the calculation row).
I can create a separate result of calculations such as the following, but it would be nice to have them somehow combined, such as shown above. In addition, the following only outputs one row of calculations, and it would be nice to have several rows of pertinent calculations.
select stddev(height), stddev(age), stddev(weight) from data [where condition];
The point here is to perform any search query and get an auto-generated preview of basic descriptive information from the results (deviations, counts, mean, etc.). Hopefully this can be done directly in SQL, without needing to use another language/API.
Combine your results with union. If you need the results in a particular order, then create a column containing the precedence and order by that column.
select id, height, age, weight, 0 sortorder
from data [where condition]
union all
select 'stdev count', stddev(height), stddev(age), stddev(weight), 1
from data [where condition]
order by sortorder

MySQL - Count column less than other column in same table

i want to COUNT column less than with other column which if Quantity in Hand < Minimum Quantity and i should get the result = 5
Instead, i got the result = 3.
| stock_id | stock_qtyhand | stock_minQty |
| 1 | 60 | 100 |
| 2 | 29 | 58 |
| 3 | 12 | 20 |
| 4 | 5 | 35 |
| 5 | 30 | 67 |
What seems to be the problem?
rsLowStock.Open "SELECT COUNT(stock_id) AS LowStock FROM stock_general WHERE stock_qtyhand<stock_minQty",conn
I appreciate your help

Percentages in MySQL - Between two columns in the same table

I have a MySQL Table that looks like this:
Name | Pass | Fail | Pass Percent | Fail Percent
Abdy | 20 | 5 | |
Bob | 10 | 5 | |
Cantona | 40 | 10 | |
Dave | 30 | 20 | |
I am trying to get the percentages:
like : passpercent = (pass/pass+fail)*100
Can I fill the table with a single MySQL code for both the columns??
The Table would look like this hopefully:
Name | Pass | Fail | Pass Percent | Fail Percent
Abdy | 20 | 5 | 80 | 20
Bob | 10 | 5 | 66 | 33
Cantona | 40 | 10 | 80 | 20
Dave | 30 | 20 | 60 | 40
That's absolutely possible.
To fill the second table:
UPDATE mytable SET pass_pct=(pass/pass+fail)*100,fail_pct=(fail/pass+fail)*100
Granted, you could also generate those during selection of the first table (if you don't want to store the results), like:
SELECT name,pass,fail,(pass/pass+fail)*100 as pass_pct,(fail/pass+fail)*100 as fail_pct FROM mytable