For my project, i have a requirement where i have to display all the records in descending order except the first record. I am kind of messed up. Anyways, i have tried the following:
SELECT * FROM ins_nr nl WHERE nl.nl_status = '2' ORDER BY nl.nl_id DESC
Here, i have a table called ins_nr which will display all the records with status 2 and the id which is the primary key(unique). It is displaying in desc order perfectly.
I dont want the first record from the top alone. What should i do? How to modify the above query..?
Use OFFSET. Then you can skip 1 records and select the remaining ones until the end.
Example:
SELECT * FROM ins_nr nl WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC LIMIT 99999999999 OFFSET 1;
OR ( You could also use a shorter syntax to achieve the same result: )
$sql = "SELECT * FROM table_name LIMIT 1, 999999999";
You can generate dynamic rownum and filter on it to omit the first row, e.g.:
SELECT *
FROM (
SELECT nl.*, #r := #r + 1 AS `rn`
FROM ins_nr nl, (SELECT #r := 0)
WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC
) a
WHERE a.rn > 1;
Another way is to get the max id from subquery and put it in a where clausole
You are looking for the offset clause. This looks like:
SELECT *
FROM ins_nr nl
WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC
LIMIT 999999999 OFFET 1;
Unfortunately, LIMIT is required. For this situation, it is traditional to just put in a very large number.
Also, if nl_status is numeric, then use nl.nl_status = 2. Don't compare strings to numbers.
Related
I have a Table with a Column 'Rechnungnr' and 'Date'
Example 2016/204, 2016/202, 2016/100, 2015/12, 2016/231
and i need the last highest number. Here -> 2016/231.
SELECT * FROM TABLE Where YEAR(Date) = '2016' ORDER BY length(`Rechnungnr`) DESC LIMIT 1
But thats not working :(
Greetz, Malte
Use a combination of char_length() and the value of rechnungnr to get the max value this way:
SELECT * FROM TABLE
Where YEAR(Date) = 2016 ORDER BY char_length(`Rechnungnr`) DESC, `Rechnungnr` DESC LIMIT 1
char_length() will order the results by the number of characters within Rechnungnr field, and then within the equally long strings, we order by the value of the field itself.
Try using column name date surrounded by backtics
SELECT * FROM TABLE Where YEAR(`Date`) = '2016' ORDER BY length(`Rechnungnr`) DESC LIMIT 1
With your existing data set (if I understand the schema correctly) you can try something like this to get the day of year, cast it to an int and then sort on it:
SELECT *, CAST(RIGHT(LENGTH(`Rechnungnr`) - (INSTR(`Rechnungnr`, '/') + 1)) AS UNSIGNED) AS `DayOfYear` FROM TABLE Where YEAR(Date) = '2016' ORDER BY `DayOfYear` DESC LIMIT 1
Im trying to get all matching records from the invoice_id field where the first 3 characters are RBK, case sensitivity not important. I've tried to use the LEFT function in the bottom 2 ways but its not working. Any ideas on how to achieve this?
SELECT *, IF( LEFT( invoice_id, 3) = 'RBK') FROM `invoices` ORDER BY id ASC
SELECT *, IF( LEFT( invoice_id, 3) = 'RBK', 3, 0) FROM `invoices` ORDER BY id ASC
an if inside the select is not to filter results,if you want to filter result use where clause.
SELECT * FROM `invoices` WHERE LEFT(invoice_id, 3) = "RBK" ORDER BY id ASC
I'm ordering a recordset like this:
SELECT * FROM leaderboards ORDER BY time ASC, percent DESC
Say I have the id of the record which relates to you, how can I find out what position it is in the recordset, as ordered above?
I understand if it was just ordered by say 'time' I could
SELECT count from table where time < your_id
But having 2 ORDER BYs has confused me.
You can use a variable to assign a counter:
SELECT *, #ctr := #ctr + 1 AS RowNumber
FROM leaderboards, (SELECT #ctr := 0) c
ORDER BY time ASC, percent DESC
Does this do what you want?
SELECT count(*)
FROM leaderboards lb cross join
(select * from leaderboards where id = MYID) theone
WHERE lb.time < theone.time or
(lb.time = theone.time and lb.percent >= theone.percent);
This assumes that there are no duplicates for time, percent.
I need to get the top half of my table in my first query and in the next query I need the bottom half.
I tried doing this for the top but it wont work
SELECT * FROM t_domains WHERE type_domain='radio' ORDER BY
date_created DESC LIMIT 0, (COUNT(*) / 2)
I need it as two queries for my function to work.
Anybody have any pointers or tips?
I would suggest doing 2 query's:
select count(*) from t_domains
to get the total count, and then get the data you want by using limit and offset:
select * from t_domains limit count/2
for the top and
select * from t_domains offset count/2
for the lower half......
This approach gives you also a way to limit the query's in another situation: what if the table contains 1 million records?
for first half
mysql-> SET #n := 0
mysql-> SELECT *,nnn FROM (
SELECT *, #n := #n + 1 AS nnn FROM t_domains ORDER BY date_created
) AS t
WHERE nnn <= ( SELECT COUNT(date_created) / 2 FROM t_domains ) AND type_domain = 'radio'
for second half, change here WHERE nnn <= this "<" on this ">"
As explained in MySQL's official documentation, LIMIT's two arguments must both be CONSTANTS except for prepared statements and stored programs. It does not seem very easy to simply store the count and later use it in a LIMIT clause.
As of version 8.0, MySQL has provided a ROW_NUMBER() function, which provides a much simpler solution than other answers have pointed out.
set #count=(select count(*)/2 from t_domains);
select * from (
select *, ROW_NUMBER() over (order by date_created desc) as row_num
from t_domains
) as t
where row_num <= #count
;
You may also check RANK(), which considers rows with equal values to have the same "ranking".
This always works.
Store the count
SELECT COUNT(*) FROM t_domains WHERE type_domain='radio'
Then use the stored count.
SELECT * FROM t_domains WHERE type_domain='radio' ORDER BY
date_created DESC LIMIT 0, {$stored_count/2}
This type of question is asked every now and then. The queries provided works, but it affects performance.
I have tried the JOIN method:
SELECT *
FROM nbk_tabl
INNER JOIN (
SELECT ITEM_NO, MAX(REF_DATE) as LDATE
FROM nbk_tabl
GROUP BY ITEM_NO) nbk2
ON nbk_tabl.REF_DATE = nbk2.LDATE
AND nbk_tabl.ITEM_NO = nbk2.ITEM_NO
And the tuple one (way slower):
SELECT *
FROM nbk_tabl
WHERE REF_DATE IN (
SELECT MAX(REF_DATE)
FROM nbk_tabl
GROUP BY ITEM_NO
)
Is there any other performance friendly way of doing this?
EDIT: To be clear, I'm applying this to a table with thousands of rows.
Yes, there is a faster way.
select *
from nbk_table
order by ref_date desc
limit <n>
Where is the number of rows that you want to return.
Hold on. I see you are trying to do this for a particular item. You might try this:
select *
from nbk_table n
where ref_date = (select max(ref_date) from nbk_table n2 where n.item_no = n2.item_no)
It might optimize better than the "in" version.
Also in MySQL you can use user variables (Suppose nbk_tabl.Item_no<>0):
select *
from (
select nbk_tabl.*,
#i := if(#ITEM_NO = ITEM_NO, #i + 1, 1) as row_num,
#ITEM_NO := ITEM_NO as t_itemNo
from nbk_tabl,(select #i := 0, #ITEM_NO := 0) t
order by Item_no, REF_DATE DESC
) as x where x.row_num = 1;