LIMIT CLAUSE With union - mysql

I have this kind of query. I am using limit, but this query gives me 20 results. Can anybody tell me why
SELECT
*,
`tablename`.`bookmark_id` as `bookmark_id`,
`tablename`.`bookmark_date` as `bookmark_date`
FROM ( (" + sql1 + ")
UNION ALL (" + sql2 + ")
UNION ALL (" + sql3 + ") ) AS tablename
WHERE `bookmark_id`
NOT IN
(SELECT `table1`.`bookmark_id`
FROM (
(SELECT `user_bookmarks`.`bookmark_id`
FROM `user_bookmarks`
WHERE `user_bookmarks`.`bookmark_id` = `bookmark_id`
AND `user_id` = 26)
UNION
(SELECT `bookmark_id`
FROM `user_deleted_bookmarks`
WHERE `user_id` = ?)
) AS `table1`)
GROUP BY bookmark_id
ORDER BY `bookmark_date`
DESC limit 17, 20
Thanks

From the SELECT docs
With one argument, the value specifies the number of rows to return from the beginning of the result set:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
I think you want LIMIT 16, 4

When you use limit, second argument is number of results to return.
See : http://dev.mysql.com/doc/refman/5.0/en/select.html
In your case you want :
SELECT .... LIMIT 16,4
You will get 4 rows : 17, 18, 19 and 20.

SELECT *,`tablename`.`bookmark_id` as `bookmark_id`,`tablename`.`bookmark_date` as `bookmark_date` FROM ( (" + sql1 + ") union all (" + sql2 + ") union all (" + sql3 + ") ) AS tablename WHERE `bookmark_id` NOT IN (SELECT `table1`.`bookmark_id` FROM ((SELECT `user_bookmarks`.`bookmark_id` FROM `user_bookmarks` WHERE `user_bookmarks`.`bookmark_id` = `bookmark_id` AND `user_id` = 26) UNION (SELECT `bookmark_id` FROM `user_deleted_bookmarks` WHERE `user_id` = ?)) AS `table1`) GROUP BY bookmark_id ORDER BY `bookmark_date`
DESC limit 16, 4;
for getting result 17,18,19,20
it's count start from 17th position and give next 4 values

Related

Is there any way to group and random some data in one sql?

I have a table with id from 1 to 10, now I need to random some data from 1 to 2, 3 to 5 and 6 to 10, such as random select 1,4,9, is there any way using one sql to resolve it?
SELECT tablename.*
FROM tablename
JOIN ( SELECT ROUND(1 * RAND() + 1) random UNION ALL
SELECT ROUND(2 * RAND() + 3) UNION ALL
SELECT ROUND(4 * RAND() + 6) ) randoms ON tablename.id = randoms.random

MySQL combine select sum and select query

I want to sum 4 cells for each row based on a previous query that will reduce the selection down to the important rows.
Basically I need to combine those two queries (which work on their own):
SELECT columnx, SUM(`column1`+ `column2` + `column3` + `column4`) as total
FROM table GROUP BY columnx
SELECT * FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
when `pos` = 'PG' then 1
when `pos` = 'SG' then 2
when `pos` = 'SF' then 3
when `pos` = 'PF' then 4
else 5
end asc
I tried to replace "table" with the second query but it's probably not the right way, since I'm getting errors here.
SELECT columnx, SUM(`column1`+ `column2` + `column3` + `column4`) as total FROM
(( SELECT * FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
when `pos` = 'PG' then 1
when `pos` = 'SG' then 2
when `pos` = 'SF' then 3
when `pos` = 'PF' then 4
else 5
end asc)
GROUP BY columnx
You were supposed to create an alias name for the block replacing table in your first query.
SELECT u.columnx, SUM(u.`column1`+ u.`column2` + u.`column3` + u.`column4`) as total
FROM (SELECT t.* FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
WHEN t.`pos`='PG' THEN 1
WHEN t.`pos`='SG' THEN 2
WHEN t.`pos`='SF' THEN 3
WHEN t.`pos`='PF' THEN 4
ELSE 5
END ASC) u GROUP BY u.columnx

MYSQL join/union with conditional limit

In this query I want a total of x number of records returned. within that query I have several sub-queries where I can't be sure if they'll return the max number of records. if one result is less than it's max limit I want to populate the remaining slots with the next query and so on. I can't do math inside a limit clause so I'm still trying to figure out how to do it. here is what I would do if math was available inside the limit clause.
select *
from
(
(select * from profile where size='local' order by rand() limit 7) as local
join
(select * from profile where size='regional' order by rand() limit (13-count(local.id)) as regional
join
(select * from profile where size='national' order by rand() limit (19-(count(local.id)+count(regional.id))) as national
join
(select * from profile where size='international' order by rand() limit (25-(count(local.id)+count(regional.id)+count(national.id)))) as international
)
I might have done this a needlessly complicated way, but it does seem to work:-
SELECT id, size
FROM
(
SELECT id, size,
#SeqLocal:=IF(size="local", IF(#SeqLocal <= 7, #SeqLocal + 1, #SeqLocal), #SeqLocal) AS SeqLocal,
#SeqRegional:=IF(size="regional", IF(#SeqLocal + #SeqRegional <= 14, #SeqRegional + 1, #SeqRegional), #SeqRegional) AS SeqRegional,
#SeqNational:=IF(size="national", IF(#SeqLocal + #SeqRegional + #SeqNational <= 21 , #SeqNational + 1, #SeqNational), #SeqNational) AS SeqNational,
#SeqInternational:=IF(size="international", IF(#SeqLocal + #SeqRegional + #SeqNational + #SeqInternational <= 28, #SeqInternational + 1, #SeqInternational), #SeqInternational) AS SeqInternational
FROM
(
select *
from profile
where size IN ("local", "regional", "national", "international")
order by FIELD(size, "local", "regional", "national", "international"), rand()
) Sub1
CROSS JOIN (SELECT #SeqLocal:=0, #SeqRegional:=0, #SeqNational:=0, #SeqInternational:=0) Sub2
) Sub3
WHERE (size = "local" AND SeqLocal != #SeqLocal)
OR (size = "regional" AND SeqRegional != #SeqRegional)
OR (size = "national" AND SeqNational != #SeqNational )
OR (size = "international" AND SeqInternational != #SeqInternational)
Sqlfiddle here:-
http://www.sqlfiddle.com/#!2/cc3b884/14

how to use limit keyword in oracle

I am retrieving data from table but instead of all row, I want 20 rows at a time for pagination. For this I use limit keyword which work perfectly in Mysql but not in Oracle.
Code:
"select "+ "C.CONTRACTOR_ID,C.CONTRACTOR_NAME,nvl(C.CONTACT_PERSON_1,'-'),nvl(C.CONTACT_PERSON_2,'-'),C.REGISTRATION_NO,CRA.DESCRIPTION REG_AUTH_NAME,"+
"to_char(C.VALID_FROM,'dd/mm/yyyy'),to_char(C.VALID_TO,'dd/mm/yyyy'),CC.DESCRIPTION CONTRACTOR_CLASS,C.INCORP_PLACE,"+
"IT.DESCRIPTION INCORP_TYPE,nvl(to_char(C.DATE_OF_INCORP,'dd/mm/yyyy'),'-') DATE_OF_INCORP,C.ADDRESS1,nvl(C.ADDRESS2,'-'),nvl(C.EMAIL_ID,'-'),"+
"nvl(C.WEBSITE_URL,'-'),nvl(C.PHONE_NO,'-'),nvl(C.FAX_NO,'-'),nvl(C.MOBILE_NO,'-'),C.BANK_NAME,C.BANK_BRANCH,C.ACCOUNT_NO,C.IFSC_CODE," +
"C.PAN_NO,nvl(C.TIN_NO,'-'),nvl(C.CST_NO,'-') "+
"from "+
"CONTRACTOR C "+
"inner join CONTRACTOR_REG_AUTH CRA on CRA.REG_AUTH_ID=C.REG_AUTH_ID "+
"inner join CONTRACTOR_CLASS CC on CC.CLASS_ID=C.CONTRACTOR_CLASS_ID "+
"inner join INCORPORATION_TYPE IT on IT.INCORP_TYPE=C.INCORP_TYPE "+
"limit " + offset + ", " + noOfRecords ";
Here no order by keyword is there. I am retrieving data from different table and then display only 20 rows at a time.
In Oracle, you can use the special rownum variable. This example behaves like limit FirstRow, NrOfRows:
select *
from (
select *
, rownum as rn
from YourTable
order by
id
) as SubQueryAlias
where FirstRow <= rn
and rn < FirstRow + NrOfRows
An optimized version of this query from AskTom, linked from this SO question:
select *
from (
select /*+ FIRST_ROWS(n) */
rownum as rn
, *
from (
select *
from YourTable
order by
id
) as SubQueryAlias1
where rownum <= FirstRow + NrOfRows
) as SubQueryAlias2
where rn >= FirstRow

MySQL Function, must bring back a row

I have this simple MySQL statement:
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
Now, if there are no rows with the date MARCH2010 then the query returns zero results (which is correct) but I'd like it to return a row - even if the result is NULL.
You can just select a single row as a constant, and then left join it to your result set:
select l.*, r.*
from (select "your constant" as constant) as l
left join (
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
) as r on 1
How this works:
select "your constant" as constant always returns a single row
left join always returns all of the rows in the left table at least once
if the right table has no rows, then the entire left table is extended with a bunch of null columns, and the result has one row
if the right table has n rows, the result has n rows that each have an additional "your constant" column
I'm not absolutely positive, but this case statement might work. I can't test it atm.
Case When
(SELECT
Count(*)
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25) > 0
Then
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
Else
SELECT null
End
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
UNION ALL
SELECT NULL AS Res
FROM dual
WHERE NOT EXISTS (
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
)
Will always return one row beacuse of second part.