How to Select 1 Row From Each 10 Rows in MySQL - php

I am recording a real time change of a given signal into my database table.
Then I draw line graph to visualize the change of the signal level.
I want to get (10n+1)th rows in the table to make a rough graph. 10 is also arbitrary. User may change it to another value.
Does someone know how to make this just using a MySQL Query
If no, I will go with PHP after selecting all the data.
Here my table structure is:
|id |signal1 |signal2 | signal 3 |
+----------+----------+----------+------------+
|1 |0.41452 | 1.32135 | 0.31231 |
...

If you have an auto_incrememt id column, you can select rows that are divisible by n
SELECT * FROM tableName1 WHERE MOD(id,10)=0;
// id divided by 10 with a remainder equal to 0 (exact)
or without sequential column id's
SELECT * FROM (
SELECT
#row := #row +1 AS rowNum, colName1
FROM (
SELECT #row :=0) r, tableName1
) ranked
WHERE rowNum % 10 = 1

If your table has auto increment id (intID), then you should try this code.There are only 26 records in my table.
select * from tablename where intId
in (select case (intId%10=0) when 1 then intId else 0 end as x from tablename )
Output :-
10 sdf KK201300010 123456 Regular
20 sdf KK201300020 123456 Regular
It will displaying each record in every 10 record.
Hope it will help you.

Related

MySql get row if id is in sequence

We require to get row if product_id is in sequence.
Table (product)
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
8 Britania
9 Pepsi
Require Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
product_id - 8 and 9 not getting because it is not in sequence.
My Try
select distinct t1.*, t1.product_id, (select GROUP_CONCAT(t2.product_id) from product as t2) as p_id
from product t1
having FIND_IN_SET(t1.product_id+1, p_id)
Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
In this try i am not getting product_id - 6 row.
Note : I want MySql query not in PHP.
Thank You !
One way i can think of is to user user defined variable to get the rank of row and then calculate the difference of product id and rank and select only those rows where difference = 0
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= 0) t
order by product_id
) t1
where diff = 0
Demo
Or if you want to pick the least sequence no. automatically you can write it as
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= (select min(product_id) from product_sale_flag) a) t
order by product_id
) t1
where diff = -1
Demo
Explanation
First query assign's minimum value of product_id to variable #row,then it assigns a rank to each row ordered by product_id in ascending order, once rank is assigned for every row then it calculates the difference between the original value of product_id and lastly using the resultant difference it checks where difference is 0 get those rows because they follow the sequence. Hope this makes sense

Avoid crossing weight range BETWEEN, with two columns? mysql

I have two columns: amountFrom , amountTo in table shipping
Lets say I have these row data:
amountFrom | amountTo
-----------------------
0 15
16 30
31 50
Now I would like to add these three:
amountFrom | amountTo
-----------------------
15 22 (should fail, already exist (crosses range))
18 25 (should fail, already exist)
55 76 (should pass)
How can I make a correct sql query, that will run for each row i would like to insert, that will check if the "range" is available?
Example of what i tried
SELECT id FROM shipping WHERE amountFrom >= 15 AND amountTo <= 22
Above query returns no rows, which it should (if it was a correct query) since we dont want to make a new row with 15 and 22, as it will cross existing weight ranges
You can try this (here with values 15 and 22) :
INSERT INTO t (amountFrom, amountTo)
SELECT 15, 22
WHERE NOT EXISTS (SELECT 1 FROM t WHERE 22 >= amountFrom AND 15 <= amountTo);
You can check the affected-rows value to see wether or not the row was actually inserted.
You don't have to do three separate inserts. You can do them all at once (at least with the data in your query).
The select statement to see which do not overlap is:
select t2.*
from table2 t2
where not exists (select 1
from table1 t1
where t1.amountFrom <= t2.amountTo and
t1.amountTo >= t2.amountFrom
);
Two ranges overlaps if one starts before the other ends, and the first ends after the other starts.
You put this into an insert as
insert into t1(amountFrom, amountTo)
select t2.amountFrom, t2.amountTo
from table2 t2
where not exists (select 1
from table1 t1
where t1.amountFrom <= t2.amountTo and
t1.amountTo >= t2.amountFrom
);
EDIT:
If you want to do this one row at a time and prevent overlap in new rows as well:
insert into t1(amountFrom, amountTo)
select t2.amountFrom, t2.amountTo
from (select XX as amountfrom, YY as amountTo
) t2
where not exists (select 1
from table1 t1
where t1.amountFrom <= t2.amountTo and
t1.amountTo >= t2.amountFrom
);
This will do the insert one step at a time with the overlap logic.

PHP function to find the median of a column in MySQL

I have a database, db and in it a table, Table.
It looks somewhat like:
id | val
--------
1 | 45
2 | 35
3 | 23
4 | 49
5 | 67
6 | 12
7 | 0
8 | 87
9 | 46
(This is just an example data set. Actual data set is huge. And I need to work in least time possible.)
I need to find the median of the column val. Actually I need a php function to be used multiple times.
A similar question does exist: Simple way to calculate median with MySQL
I tried a few answers in this question, none of them worked for me. The accepted answer doesn't work since it used to work with an older version of SQL only.
PS: It should also work in the case of many duplicates.
just for fun i thought i try and do it all in MySQL, here's the sqlFiddle
SELECT
CASE
WHEN MOD((select count(*) as count from t),2)=1 THEN
(select val from
(select #row:=#row+1 as row,val
from t,(select #row:=0)r
order by val)t1
where t1.row = CEIL((select count(*) as count from t)/2)
)
ELSE
((select val from
(select #row:=#row+1 as row,val
from t,(select #row:=0)r
order by val)t1
where t1.row = (select count(*) as count from t)/2)+
(select val from
(select #row:=#row+1 as row,val
from t,(select #row:=0)r
order by val)t1
where t1.row = ((select count(*) as count from t)/2)+1))/2
END AS median
Just replace occurences of t with your table name, don't change t1.
Also if the table has no rows, it'll return NULL as median.
This query can be further reduced to the below (sqlFiddle)
SELECT #rowCount:=(select count(*) as count from t) AS rowcount,
(select AVG(val) from
(select #row:=#row+1 as row,val
from t,(select #row:=0)r
order by val)t1
where t1.row IN (FLOOR((#rowCount+1)/2),
CEIL((#rowCount+1)/2)
)
) as Median
It'll return 2 columns, a rowcount column and a median column. I put the rowcount column there because i didn't want to count from t multiple times like previous query.

Highest rating between two columns in sql select

Say I have the following table:
--------------------
|ID|Yes|No|Filename|
|01|15 |10|1.php |
|02|12 |5 |2.php |
|03|6 |1 |3.php |
--------------------
What I want to do is apply Yes/Yes+No in an sql select statement and echo the highest value's filename.
The Yes and No are updated from time to time, so would it be better to create another column to handle the equation, or can an equation be used in a sql statment? And what would the select statment look like for this?
Thanks
for MySQL,
SELECT Filename,
CAST((Yes / (Yes + No)) AS DECIMAL(10,5)) rating
FROM table1
WHERE CAST((Yes / (Yes + No)) AS DECIMAL(10,5)) =
(
SELECT MAX(rating)
FROM
(
SELECT CAST((Yes / (Yes + No)) AS DECIMAL(10,5)) rating
FROM table1
) x
)
SQLFiddle Demo
for SQL Server
SELECT TOP 1 WITH TIES Filename,
(Yes / (Yes + No)) rating
FROM table1
ORDER BY rating DESC
SQLFiddle Demo
You can use this approach:
SELECT TOP 1 sf.Filename
, (sf.Yes / (sf.Yes + sf.No)) AS RatioValue
FROM dbo.storeFile AS sf
ORDER BY (sf.Yes / (sf.Yes + sf.No)) DESC

summing two columns total in mysql

I want a resultset for this table:
ID Number_of_posts Number_of_user
1 100 21
2 23 34
as
ID Number_of_posts Number_of_user Number_of_posts_AND_Number_of_user
1 100 21 178
2 23 34 178
-----------------------------------------------
123 55
Is it possible to get the sum of two colums as another column/ as output in mysql?
To get cross-tab totals (horizontal and vertical):
select id,
number_of_posts as p,
number_of_users as u,
number_of_posts+number_of_users as p_and_u
from tbl
union all
select 99999 as id,
sum(number_of_posts) as p,
sum(number_of_users) as u,
sum(number_of_posts+number_of_users) as p_and_u
from tbl
order by 1
This will give you:
id p u p_and_u
----- --- --- -------
1 100 21 121
2 23 34 57
99999 123 55 178
You're complicating your query needlessly and using more memory that you have to. Pull the records in one query, then make another query to get the aggregates.
I know it doesn't answer your question, but it's what you should be doing instead. =)
SELECT id, number_of_posts, number_of_user,
(
SELECT SUM(number_of_posts + number_of_user)
FROM mytable
)
FROM mytable
SELECT SUM(Number_of_posts), SUM(Number_of_user) FROM table;
SELECT *,
(SELECT SUM(Number_of_posts) + SUM(Number_of_user) FROM TABLE) AS total
FROM table;
(Edit: Didn't originally notice it was the total total in the last column.)
Does MySQL support ROLLUP?
SELECT id,
SUM(Number_of_posts) Number_of_posts,
SUM(Number_of_user) Number_of_user,
SUM(Number_of_posts) + SUM(Number_of_user) Number_of_posts_AND_Number_of_user
FROM table
GROUP BY ROLLUP(id)
Edit: based on a quick search, in MySQL the last line might be GROUP BY id WITH ROLLUP.

Categories