I wonder if there is a way to accomplish:
SELECT * FROM table
by using LIMIT and OFFSET like so:
SELECT * FROM table LIMIT all OFFSET 0
Can I write SQL statement using LIMIT and OFFSET but still getting ALL result?
* of course I can use an IF statement but I rather avoid it if possible
From the MySQL documentation:
To retrieve all rows from a certain offset up to the end of the result
set, you can use some large number for the second parameter. This
statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
So getting all rows might look as follows:
SELECT * FROM tbl LIMIT 0,18446744073709551615;
Yes, it is possible by providing NULL:
SELECT * FROM tab LIMIT NULL OFFSET NULL
db<>fiddle PostgreSQL demo
7.6. LIMIT and OFFSET
LIMIT ALL is the same as omitting the LIMIT clause, as is LIMIT with a NULL argument.
Snowflake LIMIT / FETCH
The values NULL, empty string (''), and $$$$ are also accepted and are treated as “unlimited”; this is useful primarily for connectors and drivers (such as the JDBC driver) if they receive an incomplete parameter list when dynamically binding parameters to a statement.
SELECT * FROM demo1 ORDER BY i LIMIT NULL OFFSET NULL;
SELECT * FROM demo1 ORDER BY i LIMIT '' OFFSET '';
SELECT * FROM demo1 ORDER BY i LIMIT $$$$ OFFSET $$$$;
I used this code in nodeJS with MySQL and it's run well, It's may help you.
Why you use it?
It's reliable because it's a string that will append with query.
If you want to set limit then you can put the limitation with the variable otherwise pass 0 with variable.
var noOfGroupShow=0; //0: all, rest according to number
if (noOfGroupShow == 0) {
noOfGroupShow = '';
}
else {
noOfGroupShow = ' LIMIT 0, '+noOfGroupShow;
}
var sqlGetUser = "SELECT `user_name`,`first_name`,`last_name`,`image`,`latitude`, `longitude`,`phone`,`gender`,`country`,`status_message`,`dob` as user_date_of_birth FROM `tb_user` WHERE `user_id`=?"+noOfGroupShow;
This may not be the best way to do it, but its the first that comes to mind...
SELECT * FROM myTable LIMIT 0,1000000
Replace 1000000 with some adequately large number that you know will always be larger than the total number of records in the table.
As the record will grow up, use mysql_num_rows to dynamically find total amount of records, instead of using some large number.
$cektotalrec=mysql_query("SELECT * FROM TABLE");
$numoffset=mysql_num_rows($cektotalrec);
$numlimit="0";
then:
$final="SELECT * FROM table ".$numlimit.", ".$numoffset"";
Maybe not the cleanest solution but setting limit to a very high number could work. Offset needs to be 0.
Why not use a IF statement where you add the limit and offset to the query as a statement is true?
You might receive an error if you set the limit to a very high number as defined by mysql doc. Thereofre, you should try to limit it 9999999999999, going higher can give you an error unless you set up server to go higher.
You might want to use LIMIT in a function, therefore it is not a bad idea. If you use it in a function, you might want it to be Limit All at one point and limit 1 at another point.
Below, I list an example where you might want your application to have no limit.
function get_navigation($select = "*", $from= "pages", $visible= 1, $subject_id = 2, $order_by = "position", $sort_by = "asc", $offset=0, $limit = 9551615){
global $connection;
$query = " SELECT {$select} ";
$query .= " FROM {$from} ";
$query .= " WHERE visible = {$visible} ";
$query .= " AND subject_id = {$subject_id} ";
$query .= " ORDER BY {$order_by} {$sort_by} ";
$query .= " LIMIT {$offset}, {$limit} ";
mysqli_query($connection, $query);
$navigation_set = mysqli_query($connection, $query);
confirm_query($navigation_set);
return $navigation_set;
}
define ("SELECT", "*");
define ("FROM", "pages");
define ("VISIBLE", 1);
define ("SUBJECT_ID", 3);
define ("ORDER_BY", "position");
define ("SORT_BY", "ASC");
define ("LIMIT", "0");
$navigation_set = get_navigation(SELECT, FROM, VISIBLE, SUBJECT_ID, ORDER_BY, SORT_BY);
Related
I want select X records from database (in PHP script), then sleep 60 seconds after continue the next 60 results...
SO:
SELECT * FROM TABLE WHERE A = 'B' LIMIT 60
SELECT SLEEP(60);
....
SELECT * FROM TABLE WHERE A = 'B' LIMIT X **where X is the next 60 results, then**
SELECT SLEEP(60);
AND etc...
How can I achievement this?
There is no such thing as "the next 60 records". SQL tables represent unordered sets. Without an order by, a SQL statement can return a result set in any order -- and even in different orders on different executions.
Hence, you first need something to guarantee the ordering . . . that is, an order by with keys that uniquely identify each row.
You can then use offset/limit to accomplish what you want. Or, you could put the code into a stored procedure and use a while loop. Or, you could do this on the application side.
In PHP:
<?php
// obtain the database connection, there's a heap of examples on the net, assuming you're using a library like mysqlite
$offset = 0;
while (true) {
if ($offset == 0) {
$res = $db->query('SELECT * FROM TABLE WHERE A = 'B' LIMIT 60');
} else {
$res = $db->query('SELECT * FROM TABLE WHERE A = 'B' LIMIT ' . $offset . ',60');
}
$rows = $db->fetch_assoc($res);
sleep(60);
if ($offset >= $some_arbitrary_number) {
break;
}
$offset += 60;
}
What you're doing is gradually incrementing the limit field by 60 until you reach a limit. The easiest way to do it is in a control while loop using true for the condition and break when you reach your invalid condition.
An input and script in index.php
<input type="text" class="filter" id="frClientName" name="cl_name">
<script>
$(".filter").on('change keydown keyup', function(){
var clname;
clname = document.getElementById("frClientName").value;
$("#spravaContent").load("php/search_results/sprava.php?cl_name=" + clname;
});
</script>
php/search_results/sprava.php
$clname = '';
if ( isset ( $_GET['cl_name'] ) ) {
$clname = $_GET['cl_name'];
}
$sql = ("
SELECT * FROM `db`.`table`
WHERE cl_full_name LIKE '%".$_GET['cl_name']."%'
");
How can I use WHERE clause right and only if variable isn't empty?
Thank you for some direction.
EDIT:
$sql = ("
SELECT * FROM `db`.`table`
ORDER BY {$oby} {$ohow}
WHERE cl_full_name LIKE '%".$_GET['cl_name']."%'
OR '' = '".$_GET['cl_name']."'
LIMIT $start_sprava,$per_page_sprava
");
It's a bit hacky, but I've handled situations like this with a CASE statement. You evaluate your argument and if it doesn't meet the condition you require, you use an obviously true statement like 1=1 which has the net effect of keeping that part of the WHERE clause from participating in filtering the result set.
SELECT *
FROM `db`.`table`
WHERE CASE WHEN TRIM('".$_GET['cl_name']."') IS NOT NULL THEN cl_full_name LIKE '%".$_GET['cl_name']."%'
ELSE 1=1
END
ORDER BY {$oby} {$ohow}
LIMIT {$start_sprava}, {$per_page_sprava}
;
Don't forget to police your inputs so you don't wind up with a Little Bobby Tables problem. Also, the ORDER BY and LIMIT clauses generally come after the WHERE clause.
Make the where clause work whether set or not.
Assuming your app language returns the text "null" if variable is not set:
"SELECT * FROM `db`.`table`
WHERE cl_full_name LIKE '%".$_GET['cl_name']."%'
OR 'null' = '".$_GET['cl_name']."'"
I'm just a beginner at mysql so in school we got task to do. It goes like this. Display / print 10% of all books from books in falling order. So i tried to use limit, but it doesn't work. What can i do? My code i've tried to use:
select title, price from book
order by price desc
limit (select count(*)*0.1 from book);
thank you for your answers!
limit values have to be hard-coded constants. You can't use variables on them, e.g. select ... limit #somevar is a syntax error. You also can't use sub-queries or other dynamic values either. So you're stuck with either fetching the row count ahead of time and stuff it into the query string as a "hard-coded" value:
$ten_percent = get_from_database('select count(*) / 10 from book');
$sql = "SELECT .... LIMIT $ten_percent";
Or you simply fetch everything and then abort your loop once you've reached 10%:
$sql = "SELECT ....";
$result = mysql_query($sql) or die(mysql_error());
$total_rows = mysql_num_rows($result);
$fetched = 0;
while($row = mysql_fetch_assoc()) {
$fetched++;
if ($fetched >= ($total_rows / 10)) {
break; // abort the loop at 10%
}
... do stuff with $row
}
I have a query that is running
$this->db->select('Parent_Username, Program_Subtype, Is_Chaperone,Participant_name,Role,Percent_completed,Wizard_ID');
$this->db->where('Parent_Username', $username);
$this->db->where('Program_ID', $Program_ID);
$query = $this->db->get($this->child_table);
an echo produces:
SELECT `Parent_Username`, `Program_Subtype`, `Is_Chaperone`, `Participant_name`,
`Role`, `Percent_completed`, `Wizard_ID` FROM (`child_table`)
WHERE `Parent_Username` = 'test123' AND `Program_ID` = 'abcdef3423' LIMIT 1
So where is that Limit 1 coming from, when I don't specify it, I need all records, I can set an arbitrary limit like $this->db->limit('502340234234235'); but why should I have to, why is it limiting it to 1 record when I don't specify it to?
I have a multi-table SQL query.
My need is: The query should I generate a single line by 'etablissement_id' ... and all information that I want to be back in the same query.
The problem is that this query is currently on a table where "establishment" may have "multiple photos" and suddenly, my query I currently generates several lines for the same id...
I want the following statement - LEFT JOINetablissementContenuMultimediaON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId - only a single multimedia content is displayed. Is it possible to do this in the query below?
Here is the generated query.
SELECT DISTINCT `etablissement`. * , `etablissementContenuMultimedia`. * , `misEnAvant`. * , `quartier`. *
FROM `etablissement`
LEFT JOIN `etablissementContenuMultimedia` ON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId
LEFT JOIN `misEnAvant` ON misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id
LEFT JOIN `quartier` ON quartier_id = etablissement_quartierId
WHERE (
misEnAvant_typeMisEnAvantId =1
AND (
misEnAvant_dateDebut <= CURRENT_DATE
AND CURRENT_DATE <= misEnAvant_dateFin
)
)
AND (
etablissement_isActive =1
)
ORDER BY `etablissement`.`etablissement_id` ASC
LIMIT 0 , 30
Here is the code used ZF
public function find (){
$db = Zend_Db_Table::getDefaultAdapter();
$oSelect = $db->select();
$oSelect->distinct()
->from('etablissement')
->joinLeft('etablissementContenuMultimedia', 'etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId')
->joinLeft('misEnAvant', 'misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id')
->joinLeft('quartier', 'quartier_id = etablissement_quartierId ')
->where ('misEnAvant_typeMisEnAvantId = 1 AND (misEnAvant_dateDebut <= CURRENT_DATE AND CURRENT_DATE <= misEnAvant_dateFin) ')
->where ('etablissement_isActive = 1')
->order(new Zend_Db_Expr('RAND()'));
$zSql = $oSelect->__toString();
if(isset($_GET['debug']) AND $_GET['debug'] == 1)
echo $zSql ;
//die();
$oResultEtablissement = $db->fetchAll($oSelect);
return $oResultEtablissement ;
}
Can you help me?
Sincerely,
If you are looking to have only one of the media displayed out of many regardless of which it may be then you can just add a limit to the query? After that you can tweak the query for ASCending or DESCending perhaps?
Is this query supposed to have images (or image as it were) for one establishment, or one image each for each active establishment? I see you have a limit 0,30 which means you're likely paginating....
If the result you want is a search for only one establishment, and the first image it comes to would work fine .. just use "limit 1" and you'll only get one result.
I took the time to redo the whole model of the database ... and now it works. There was no solution for a system as flawed