write multiple where filtering in mysql - php

how can i write a sql like this?
$sqlNext = "select * from table WHERE (status='normal') AND (number = (select max(number) from table where number < 5)) LIMIT 1";
in first step filter the result by status column, after that
search in rows with number value less than 5 in status='normal' rows.
in this sql first part of AND=>status='normal' IS NOT WORK
just send me max row with number value less than 5

Isn't this what you're looking for?
select max(number), status from table WHERE status='normal' and number < 5

Related

PHP & MYSQL - ORDER BY id sometimes returns nothing

I am trying to wrote a PHP script that will pull a random row from a MYSQL table. So far, the code successfully grabs a random row, but sometimes it will return nothing, and I don't understand why.
$result = $conn->query("SELECT fact
FROM numfacts
WHERE number = '".(string)$number."'
AND id >= (SELECT FLOOR( MAX(id) * RAND()) FROM numfacts )
ORDER BY id
LIMIT 1");
The value for $number is currently 12, and there are two rows containing this in the database. Roughly 2/3 times the code returns a value, and the other 1/3 of times it returns 0 results.
If you need more code, I will provide it.
The part of the WHERE clause with id >= (SELECT FLOOR( MAX(id) * RAND()) FROM numfacts ) restricts the query to looking in a subset of the table. If the two rows with number = 12 are not in this subset, the query doesn't return anything. And since the subset is specified randomly, this will only happen some of the time.
To ensure that the subset includes at least one of the rows with number = 12, you can include that criteria in the subquery.
SELECT fact
FROM numfacts
WHERE number = '".(string)$number."'
AND id >= (SELECT FLOOR( MAX(id) * RAND())
FROM numfacts
WHERE number = '$number' )
ORDER BY id
LIMIT 1
Note that this query doesn't provide very fair selection of rows. Because it uses ORDER BY id, it's biased towards low-numbered rows. This method is reasonable when you're just trying to select a random row with no other filtering, but when you add the number = 12 criteria it becomes unfair. For instance, if the IDs of the two rows are 50 and 75, you'll choose the lower one 2/3 of the time.
You can get an unbiased selection with:
SELECT fact
FROM numfacts
WHERE number = '$number'
ORDER BY RAND()
LIMIT 1
If subquery SELECT FLOOR( MAX(id) * RAND()) FROM numfacts will return something less then $number the entire query will return nothing.

Variable limit on dataset using PDO

I'm searching a very large database and would like to limit the rows returned based on this criteria.
My query looks like this
SELECT id,value,year FROM table WHERE value = '$formvariable'
All I really want is this:
If more than 250 rows are returned by the query show only the last 3 years of results ordered by year descending, limit 1000.
Otherwise 250 rows or less, show all.
You can try doing something like this:
SELECT * FROM YourTable
WHERE value = '$formvariable'
AND 250 >= (SELECT COUNT(*) FROM YourTable)
UNION ALL
SELECT * FROM YourTable t
WHERE value = '$formvariable'
AND 250 <= (SELECT COUNT(*) FROM YourTable)
AND t.year >= YEAR(DATE_ADD(curdate(), INTERVAL -3 YEAR))
ORDER BY t.year DESC
LIMIT 1000
In case there are less then 250 records, all will be selected in the first part of the UNION, and none will be selected from the second.
In case there are more, none will be selected from the first part, and only the 1000 first records of the past 3 years ordered by year will be selected.

how to retrieve all rows from a table starting from the n'th row

I want to retrieve all rows from a table starting from the n'th row.
For example, if the table has 20 rows and n=9, I want to retrieve all elements Where the first part of the retrieved elements are the elements from 9 to 20 and the second part are form 1 to 8.
[9,10,...,19,20,1,2,...,7,8].
At first,I thought that I can use 2 queries to do that using LIMIT and OFFSET .
//retrieve the 2nd group
SELECT * FROM Tname WHERE 1 LIMIT (Tsize-n+1) OFFSET (n)
//retrieve the 1st group
SELECT * FROM Tname WHERE 1 LIMIT (n-1)
Where I calculate Tsize-n+1, n and n-1 before, and after retrieving elements I combine the two arrays.
But I don't think that this is the optimal solution (I don't want to use more than one query. and calculating the number of elements in the table is consuming).
Is there a better way to do that?
I have a simple idea. Just select all rows, then read first n rows and finally read remaining rows to the end. Just that!
You can also try this :
(SELECT * FROM Tname WHERE id >= n)
UNION (SELECT * FROM Tname WHERE id < n)
You can use small trick to do this:
SELECT * FROM Tname ORDER BY id >= n DESC, id ASC
This way you have results in that order [9,10,...,19,20,1,2,...,7,8].
If that didn't work (you don't know what id must be used as boundary) you can rearrange results in PHP:
$n = 9;
$resultsArray = array_merge(
array_slice($resultsArray, $n),
array_slice($resultsArray, 0, $n)
);
just reverse order by any column and pass the offset and limit
$data = SELECT * FROM table;
in php
krsort($data);
$chunked_data = array_chunk($data,9);

how to select sum limit to X number mysql

$query = "SELECT sum(DAILYTIME) FROM $mytable LIMIT 5";
that statement selects and sums limited to 5 rows, but how to do it based on certain row. For example I want to use row #10 as a starting point and sum 5 rows below that one ( 5 rows including that same row ).
how would the statement need to be, because if i do WHERE DAY = '$day' LIMIT 5
it will not sum all the 5 rows, just 1
By adding a where clause with the >= operator, you will also select all following rows. Use the following query:
$query = "SELECT sum(DAILYTIME) FROM $mytable WHERE DAY >= '$day' LIMIT 5";
This will give you the sum of the 10th through 14th "rows"; however, since there is no ORDER BY, there is no guarantee which rows of the table the result rows of the subquery would be.
SELECT sum(DAILYTIME)
FROM (
SELECT DAILYTIME
FROM $mytable
LIMIT 9, 5
) AS `rows10to15`
;

Most efficient way to calculate affected rows with a limit

I have a column result in my table and want to know how many rows are affected where result contains a specific number like '3' in the last 25 rows before a specific id.
Eg: Want to know how many rows have a result = 3 of the 25 rows before the id "500".
What is the most efficiƫnt way to reach this in Php and MySQL.
You can do that completely with SQL:
SELECT COUNT(x.result)
FROM (
SELECT *
FROM table
WHERE id < 500
ORDER BY id DESC
LIMIT 25
) x
WHERE x.result = 3
First you find all entries that are relevant to your query by specifying the search criteria. Then you limit this search to 25 items and sort it in reverse order. That should yield the 25 last elements. Finally you just do your COUNT() for items with a result value of 3.
SELECT COUNT(result)
FROM table
WHERE id < '$specificID'
AND result = 3
ORDER BY id DESC
LIMIT 25
Try this
SELECT count(*) FROM `your_table`
WHERE result LIKE '%3%'
AND id < 500
ORDER BY id ASC
LIMIT 25;

Categories