I am using phpMyAdmin to write some SQL code that I thought was simple but proving to be a headache. I'm using this tutorial to help me out. My goal is to get the first and last columns id's from a result set. When I do this query I get 5 rows starting at 15 and going through 11.
SELECT id
FROM boardPost
WHERE recipientId = 1
ORDER BY id DESC
LIMIT 0,5
However, when I try this query I get an error #1064: "You have an error in your SQL syntax."
SELECT FIRST(id)
FROM boardPost
WHERE recipientId = 1
ORDER BY id DESC
LIMIT 0,5
Something like this maybe?
SELECT min(id), max(id)
from (
select id
from boardPost
where recipientId = 1
order by id desc
limit 0,5
) t
I think that is what you want?
Select id from boardPost order by id asc limit 1
and
Select id from boardPost order by id desc limit 1
If you just want the first and the last id of a result set, you could consider this:
SELECT MIN(id) firstId, MAX(id) lastId FROM someTable WHERE aField = 1;
Note that it'll only work if you do use and ORDER BY an AUTO_INCREMENT field, else you might get unexpected results.
It'll only work with the full set. If you need the first and last id of a limited one, you're probably better of using 2 queries with ASC and DESC order and LIMIT 1.
MySQL does not support the FIRST() function. You will need to use the workaround they specified in that tutorial (using ORDER BY and LIMIT)
In some situations (like mine, that first brought me here), there are some rarely-used MySQL "windowing functions" such as FIRST_VALUE and LAST_VALUE that may provide the functionality you're seeking.
(Here's more info on Window Function Concepts and Syntax, and the Wikipedia description of the term.)
Related
First of all, I am using MySQL. When I make the following query:
SELECT CodE,sum(tiempo) AS 'tiempo total'
FROM Participa
GROUP BY CodE
ORDER BY 'tiempo total' DESC LIMIT 1;
it shows me the first line of my table instead of the MAX value. However, If I make the following query:
SELECT CodE,sum(tiempo)
FROM Participa
GROUP BY CodE
ORDER BY 2 DESC LIMIT 1
I get the correct result.
I have just changed the alias 'tiempo total' for somthing that should be equivalent.
How it´s possible?
Only use single quotes for string and date constants -- never for column aliases. So:
SELECT CodE, sum(tiempo) AS `tiempo total`
FROM Participa
GROUP BY CodE
ORDER BY `tiempo total` DESC
LIMIT 1;
You are ordering by a constant string, not the name of a column. Hence, if you get the maximum in your query, it would be a total accident.
Note: You can get around these issues by giving columns names that never need to be escaped:
SELECT CodE, sum(tiempo) AS tiempo_total
FROM Participa
GROUP BY CodE
ORDER BY tiempo_total DESC
LIMIT 1;
Easier to type, too.
I am writing a query, but I only want to search the first 10 records in the table. I know that in a select limit usually limits the records, but it doesn't work for this instance.
eg
SELECT * FROM `logon` WHERE `username`='superman' ORDER BY `user_id` LIMIT 10
The above line will never work because the query only returns one.
I only want to search through the first 10 records, and limit doesn't work in this case.
So how do I limit my search to the first 10 records?
SELECT * FROM
(SELECT * FROM `logon` ORDER BY `user_id` LIMIT 10) as temp
WHERE temp.`username`='superman';
You can simply write a subquery which returns the "first" 10 records and put a where clause on the result set.
SELECT *
FROM `logon`
WHERE `username`='superman'
and user_id in (select user_id from logon order by user_id limit 10)
(I haven't tried this, but I think it's the fastest way to do this)
Use order by
SELECT * FROM `logon` WHERE `username` = 'superman' ORDER BY user_id LIMIT 10
Not the right Way...but can be done...
SELECT *
FROM logon
WHERE username='superman' AND srno BETWEEN 1 AND 10;
I've got a query that is returning a set of rows. I want to LIMIT what actually gets returned to some subset of these rows by range, relative either to the beginning or end of the range. I can do this easily if the range is only relative to the beginning. For instance, if I want to return rows 5-7 I can do:
SELECT * FROM <table> WHERE <condition> ORDER BY rowid ASC LIMIT 5,2
The only translation I need to do is from (index0,index1) to offset,length where offset=index0 and length=index1-index0.
But I also am trying to allow the range to be specified relative to the end of the range in a single query, i.e. without running a query first to determine the number of rows and then a second query based on this information. So for example if I specify a row range of (-5,-1) this means that I want the last five rows returned. I cannot pass a negative value to LIMIT.
In reading similar questions, one proposed solution seemed to be to change the ORDER of the query. So I suppose I could do:
SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 1,5
Now I have two problems. First, the returned set is in the wrong order, I still want it return in ascending order. So now I have to have a subquery to reorder everything:
SELECT * FROM (SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 1,5) AS x ORDER BY x.rowid ASC;
I'm not sure if there is a better way to do it than that, but there is a second issue: this does not work if the starting and ending part of the range are mixed as to what they are relative to. Suppose I want to return the range (10,-2) which is all rows from the tenth to the next to last. In this case, neither of the above approaches will work.
I also saw where the function mysql_num_rows() was mentioned although it did not give example SQL of how to use it.
SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 10,mysql_num_rows()-2;
But when I try to run this query, I get this error:
ERROR 1327 (42000): Undeclared variable: mysql_num_rows
What about reversing your approach? Asking for rows in range (10, -2) means "everything except first nine rows and last one".
You can translate it into
select * from yourTable order by rowid asc
minus
select * fom yourTable order by rowid asc limit 9
minus
select * fom yourTable order by rowid desc limit 1
Edit
Since MySQL does not support MINUS, the query above could be rewritten using left join instead
select t1.*
from yourTable t1
left join
(select rowid fom yourTable order by rowid asc limit 9) t2
on t1.rowid = t2.rowid
left join
(select rowid fom yourTable order by rowid desc limit 1) t3
on t1.rowid = t3.id
where t2.rowid is null and t3.rowid is null
order by t1.rowid asc
This is based on a different answer that was given to this question, which used MINUS. Unfortunately, MySQL does not support this operator. I used NOT IN instead, and furthermore I had to wrap my query inside additional queries to avoid the MySQL issue of lack of support for LIMIT being in an IN sub-query.
So the premise of the solution as provided by the other answer is to treat a positive starting index and a negative ending indexes as a different case from both indicies negative or positive. Then, select everything but exclude the range at the start and finish. The actual code that MySQL likes and which works for the example range of (10,-2) is:
SELECT *
FROM <table>
WHERE <conditions>
AND rowid NOT IN
(
SELECT * FROM (
SELECT rowid FROM <table> WHERE <conditions> ORDER BY rowid ASC LIMIT 9
)
)
AND rowid NOT IN
(
SELECT * FROM (
SELECT rowid FROM <table> WHERE <conditions> ORDER BY rowid DESC LIMIT 1
)
)
Or more generally, for the range (i0,i1) where i0>=0 and i1<0, replace 9 with i0-1 and 1 with -i1-1. Of course, if either of these values are less than one, that portion of the query can be excluded.
I need to be able to display the results of the below query in a specific order. For example: showing featured listings before the rest of the results.
WHERE IS `featured-listing` && WHERE IS NOT `featured-listing`
Could probably run 2 queries and a union right, bu is that the most effective solution? I know this can be done with one query I just cant remember how it/s done. Any and all help is appreciated.
SELECT `Assigned-Regions`,`Description`,`Category`,`Start-Date` FROM `adds` WHERE `Status` = "Active" ORDER BY `Start-Date` DESC
I would use a case statement for ORDER BY.
So something like
SELECT ... ORDER BY (CASE WHEN featured-listing THEN 1 ELSE 2) ASC, some-other-field ASC
Sounds like all you need is to add an ORDER BY clause to your query.
If featured-listing column is integer datatype and contains values of 1 or 0 (1=is featured listing, 0=not a featured listing), then you could simply add something as simple as:
ORDER BY `featured-listing` DESC, `Start-Date` DESC
Or, you could use an expression:
ORDER BY IF(`featured-listing`=1,1,0) DESC, `Start-Date` DESC
you can do conditional ordering.. not sure what featured-listing is without seeing some data but this is the logic for conditional ordering
SELECT `Assigned-Regions`,`Description`,`Category`,`Start-Date`
FROM `adds`
WHERE `Status` = "Active"
ORDER BY
CASE WHEN `featured-listing` THEN 1 ELSE 2 END ASC,
`Start-Date` DESC
I'm trying to understand COUNT(*), and therefore I created a testing query:
SELECT COUNT(*)
WHERE COUNT(UITLENINGEN.LLNR) >= 30;
When I click Execute, I get the following error:
Syntax error (operator missing) in query-expression COUNT(*) WHERE COUNT(UITLENINGEN.LLNR) >= 30.
What am I doing wrong?
Try this
SELECT COUNT(*) FROM UITLENINGEN GROUP BY LLNR HAVING COUNT(UITLENINGEN.LLNR) >= 30;
I don't understand what you're trying to do. The query below is based on a table which includes a field named category_id. And it uses GROUP BY category_id to count the number of rows within each such group. The HAVING clause limits the result set to only those groups whose count is at least 30.
SELECT category_id, COUNT(*)
FROM YourTable
GROUP BY category_id
HAVING COUNT(*) >= 30;
If that is nothing like what you're trying to accomplish, please give us more detailed information so we may better understand your situation. A brief set of sample data, and the output you want based on that sample, would help tremendously.
You have not specified the table from which the data should be retrieved. Try the following
SELECT COUNT(*) from tableName
WHERE COUNT(UITLENINGEN.LLNR) >= 30;
Add your table name to the query.
SELECT COUNT(*) FROM UITLENINGEN WHERE COUNT(UITLENINGEN.LLNR) >= 30;
Please, add table name and use having statement where aggregation funcion required. E.g.:
select count(*)
from UITLENINGEN
having count(UITLENINGEN.LLNR) >= 30;