I have a table which has data from a graph.
for example
index value
0 3
1 5
2 7
3 6
4 8
5 9
6 12
7 11
8 10
9 14
10 13
I need to a query that returns the results where the value is at a local maximum, i.e. the value at a particular index is greater than the value at index+1 and index-1.
So for the example set, it should return the list of indexes: 2, 6, 9 corresponding to values 7, 12, 14.
I'm using PHP with SQLite.
I can do it with a foreach-loop in php, but was wondering if there's an easy way to do it using just SQL commands.
Any input would be appreciated.
Or use sub-queries (this is tested):
select ind
from tmp1 t1
where val > (select val from jdoyle.tmp1 t2 where t2.ind = t1.ind-1)
and val > (select val from jdoyle.tmp1 t2 where t2.ind = t1.ind+1);
Doing this with a single loop in PHP is likely to be much faster than shoehorning this into an SQL query, but if you really want to you could self-join the table with itself with something like:
SELECT b.index
FROM points AS a, points AS b, points AS c
WHERE a.index = b.index-1 AND c.index = b.index+1
AND a.value < b.value AND c.value < b.value
(Untested, so *cross fingers*.)
You could write your loop inside a stored procedure in SQL if your SQL database supports stored procedures. However, I don't think sqlite has rich enough stored procedures to do something like this, you would need to use mysql, postgresql or similar.
Well, if you're using sqlite on production I imagine that you don't have a huge bunch of data. Considering this, the best solution really is to solve it at php level.
Related
I have 2 million rows in a myqsl DB which have multiple columns of contacts as phone_1, phone_2 upto phone_10.
These phone no. may or may not duplicate.
I intend to group them together..as
ID Contact_1 Contact_2 Contact_3
P1 1 2 3
P2 5 6 7
P3 2 8 9
result should be:
ID Contact_1 Contact_2 Contact_3 Group
P1 1 2 3 1
P2 5 6 7 2
P3 2 8 9 1
P3 11 12 13 3
P3 7 21 22 2
Now where should I do the processing part ...PHP/Python or mysql.
i.e. select the entire data in php script and create an arrray and process tha array and then use insert query.
OR
select the entire data in php script and then use UPDATE(with a logic to create groups) query.
??
I have group field in DB table.
It depends, I'd say mostly on how comfortable you are with each language. I would probably do this with PHP, but that's the language I know best.
You can certainly do it purely with MySql, and the operation would probably run faster, but it might be easier to debug and test each step in PHP or Python.
Regardless, I'd recommend first creating a data subset, maybe 1000 or 2000 rows from the table and running everything against that until you're happy with the results. It'll be much much faster and you'll see mistakes sooner.
Also, I'd avoid running anything you're worried about being slow on a production server.
I'm developing a web-based tool that can help analyze number intervals that occurs in a 6-digit lottery.
Let us focus on a certain number first. Say 7
The sql query I've done so far:
SELECT * FROM `l642` WHERE `1d`=7 OR `2d`=7 OR `3d`=7 OR `4d`=7 OR `5d`=7
OR `6d`=7 ORDER BY `draw_date` DESC LIMIT 2
This will pull the last two latest dates where number 7 is present
I'm thinking of using DATEDIFF but I'm confused on how to get the previous value to subtract it on the latest draw_date
My goal is to list the intervals of numbers 1-42 and I'll plan to accomplish it using PHP.
Looking forward to your help
A few ideas spring to mind.
(1) First, since you perfectly have your result set ordered, use PHP loop on the two rows getting $date1 =$row['draw_date']. Then fetch next/last row and set $date2 =$row['draw_date']. With these two you have
$diff=date_diff($date1,$date2);
as the difference in days.
(2)
A second way is to have mysql return datediff by including a rownumber in the resultset and doing a self-join with aliases say alias a for row1 and alias b for row2.
datediff(a.draw_date,b.drawdate).
How one goes about getting rownumber could be either:
(2a) rownumber found here: With MySQL, how can I generate a column containing the record index in a table?
(2b) worktable with id int auto_increment primary key column with select into from your shown LIMIT 2 query (and a truncate table worktable between iterations 1 to 42) to reset auto_increment to 0.
The entire thing could be wrapped with an outer table 1 to 42 where 42 rows are brought back with 2 columns (num, number_of_days), but that wasn't your question.
So considering how infrequent you are probably doing this, I would probably recommend not over-engineering it and would shoot for #1
I'm recently migrating from MySQL to Postgres, as I am now running a OSM tile server that requires Postgres / Postgis in order to function, and I see no reason to waste RAM by having 2 databases running at the same time. I am noticing many nuances in Postgres but one thing that bugs me is division does not seem to be working. I can not divide! Am I doing something wrong here? 197/201 should return 0.980099502
Core=# SELECT SUM(197/201);
sum
-----
0
(1 row)
Core=# SELECT SUM(197+201);
sum
-----
398
(1 row)
Core=# SELECT SUM(197*201);
sum
-------
39597
(1 row)
Core=# SELECT SUM(197-201);
sum
-----
-4
(1 row)
Postgres does integer division, so 1/2 = 0. You can try to add a decimal point to get another answer, 1.0/2.
You can read the documentation here.
Here's my table structure...
TABLE : position_hierarchy_level
id parent_position_id position_id
1 1 2
2 2 3
3 3 4
4 4 5
5 5 6
6 6 7
7 7 8
8 8 9
9 9 10
10 10 11
11 11 12
12 12 13
13 13 14
14 14 15
My query for getting the parent_position_id of a certain position_id is:
select `parent_position_id` from `position_hierarchy_level` where position_id= 15;
But how can I get the top-most parent of a certain position_id? For example, the top-most parent_position_id of position_id 15 would be 1.
Is there a convenient way to get this value using a single query? Or do I need to create a loop in PHP?
Your database structure wouldnt let you do it unless there are 15 or more joins. You are using Adjacency list model. Try using The nested set model
Here is an example with php
Try this:
DELIMITER $$
CREATE FUNCTION getTopParentPositionId(positionId INT) RETURNS INT DETERMINISTIC
BEGIN
DECLARE x INT;
DECLARE y INT;
SET x = positionId;
sloop:LOOP
SET y = NULL;
SELECT parent_position_id INTO y FROM position_hierarchy_level WHERE position_id = x;
IF y IS NULL THEN
LEAVE sloop;
END IF;
SET x = y;
ITERATE sloop;
END LOOP;
RETURN x;
END $$
DELIMITER ;
Then:
SELECT getTopParentPositionId( 5 );
Obviously, you are not the only one who looked into thoose kind of solution :)
Looks like the same problem:
Recursive PHP function for adjacency-list display
Using a single query with mysql could be kind of different. Maybe you could solve this with a stored procedure.
if i understand correctly and you want to highest position_id to have 1 for parent_position_id and so on ...
1 . SET parent_position_id to auto increment
2 . select position_id from table order by position_id desc and put them in a array
3 . truncate table
4 . insert array to table
With this table structure the best option you have is a loop in php end of things.
If the table structure is something you can freely change (in case if project isn't live already), you might want to look into structure called Closure Tables. You can find a simple example of how the are used/setup in this article.
In any case, you should be able to find a lot more on the subject in the SQL Antipatterns book.
Is there a convenient way to get it using a single query?
I think NO, take look here for Hierarchical queries in MySQL
do I need to create a loop statement in PHP?
I think YES.
Hey, first I use SQL + PHP the type of DB is MYSQL.
I have a column with the many strings, but I want to search the string 08/08/10 if it exists 5 times for example in the column, how do I do it?
** If I will do:
SELECT * FROM x WHERE y LIKE '%08/08/10%'
Maybe it exists, but I don't know if 5 times..
Thank you very much!
select count(1) from x where y like '%08/08/10%' -outputs exact number of rows that have y like '%08/08/10%'
no group by needed in this particular case.
fetch rows where the string exists at least once and use php (e.g. substr_count) to count occurrences.
foreach($db->fetchAll(" where y like '%blah%' ") as $rec)
if(substr_count($rec->y, "blah") == 5)
bingo...
it also may help to tell us more about your problem - maybe there are better ways to structure the database