Select 4 rows at random with minimum values in sqlite - sql

I have the following table:
addition
question answer box
1 + 1 2 0
1 + 2 3 2
1 + 3 4 1
1 + 4 5 2
1 + 5 6 3
1 + 6 7 1
I'm trying to select 4 rows with a minimum box value:
SELECT *, MIN(box) FROM {table} ORDER BY RANDOM() LIMIT 4;
However, it returns only one row.

Sounds like you want a cartesian product (CROSS JOIN) of two tables: the first table being what you presented above, and the second being the minimum value for column box.
Try this
SELECT * FROM {table}
CROSS JOIN
(SELECT MIN(box) from {table})
ORDER BY RANDOM() LIMIT 4;
Notice the subquery in the second half of the CROSS JOIN.

Related

Row Number with specific window size

I want to group records by row numbers.
Like from row 1-3 in group 1 , 4-6 in group 2 , 7-9 in group 3 and so on.
Suppose below is the table structure:
Row NumberDataValue
1 A 10
2 A 5
3 A 1
4 A 33
5 A 2
6 A 127
1 B 1
2 B 0
3 B 7
4 B 7
5 B 5
6 B 8
7 B 1
8 B 0
I want a output like this:
GroupValue
1 10
1 5
1 1
2 33
2 2
2 127
1 1
1 0
1 7
2 7
2 5
2 8
3 1
3 0
I am using Oracle 11G.
I can achieve this using PL/SQL. But I have to use SQL only. As I have to use this query in a reporting tool.
If this is a duplicate question please provide the link of the answered question.
Subtract 1 from the column "RowNumber" and divide by 3.
Then use TRUNC() to get the integer part:
SELECT TRUNC(("RowNumber" - 1) / 3) + 1 "Group",
"Value"
FROM tablename
See the demo.
I would assume the name of the first column is ordering.
You can do:
select
1 + trunc(row_number() over(partition by data order by ordering) - 1) / 3,
value
from t
What you show looks like the output from something like this:
select ceil(rn/3) as grp, value
from your_table
order by rn;
Note that "row number" and "group" are reserved words/phrases which should not be used as column names. I used rn and grp instead.
I think the ceiling function is the simplest way to arrive at what you want. If you want to base it on the RowNumber column:
select ceil( RowNumber / 3.0) as grouping
If you want to calculate it yourself using row_number():
select ceil( row_number() over (order by RowNumber) / 3.0 ) as grouping

Select Top N Random rows from table then ordering by column

I need to get 3 random rows from a table and then order those rows by a the BannerWeight column.
So if the data is:
BannerID BannerWeight
1 5
2 5
3 10
4 5
5 10
I want the results to be:
BannerID BannerWeight
5 10
2 5
4 5
So far I have:
SELECT TOP 3 b.BannerID, b.BannerWeight FROM CMS_Banner b
INNER JOIN CMS_BannerCategory c ON b.BannerCategoryID = c.BannerCategoryID
WHERE c.BannerCategoryName LIKE 'HomepageSponsors'
ORDER BY NEWID()
I just can't figure out how to order those 3 random rows once I get them. I've tried doing
ORDER BY BannerWeight, NEWID()
But this just gets me 3 random rows where the BannerWeight is 5.
Here is an SQLFiddle: http://sqlfiddle.com/#!6/a8088/2/0
Easiest option (I think) is to use a subquery:
Select * from
(
SELECT TOP 3 b.BannerID, b.BannerWeight FROM Banners b
ORDER BY NEWID()
) a
order by a.bannerweight

Generate a sequence number for every 3 rows in SQL

I need to generate a sequence number for every three rows with some range. can this be done without iterations.
Example:
sequence
--------
1
1
1
2
2
2
3
3
3
Use this Analytic function
SELECT ( ( Row_number()OVER(ORDER BY order_by_column ) - 1 ) / 3 ) + 1 seq_no,
*
FROM tablename

how to get the even and odd column separately with separate column by query

I have an input:
id
1
2
3
4
5
6
7
8
9
10
I want get even and odd columns separately by columns in specified output like this
id col
1 2
3 4
5 6
7 8
9 10
here id and col are separate columns id contains the odd number and col contains the even number for specified input
SELECT MIN(id) as id, MAX(id) as col
FROM YourTable
GROUP BY FLOOR((id+1)/2)
For IDs 1 and 2, (id+1)/2 are 2/2 = 1 and 3/2 = 1.5, respectively, and FLOOR then returns 1 for both of them. Similarly, for 3 and 4, this is 2, and so on. So it groups all the input rows into pairs based on this formula. Then it uses MIN and MAX within each group to get the lower and higher IDs of the pairs.
Joined the table on itself
select *
from yourTable tA
left join yourTable tb on tA.id = (tB.id - 1)
where tA.id % 2 <> 0
If you use SQL you can try:
SELECT CASE WHEN column % 2 = 1
THEN column
ELSE null
END AS odds,
CASE WHEN column % 2 = 2
THEN column
ELSE null
END AS even
FROM yourtable
but not exactl as you ask
To show odd:
Select * from MEN where (RowID % 2) = 1
To show even:
Select * from MEN where (RowID % 2) = 0
Now, just join those two result sets and that's it.
Source

Sum a column and get the first row in Transact Sql

I have a table MOUVEMENTS which has 3 columns :
ID IDREF NUMBER
1 1 5
2 1 3
3 1 4
4 1 2
5 2 1
I'd like to fetch the rows of this table with that constraints :
IDREF = 1
Ordered by ID ASC
and the X first SUM of NUMBER (by IDREF)
I imagine that we will first calculate the SUM. And then we will restrict with that column
ID IDREF NUMBER SUM
1 1 5 5
2 1 3 8
3 1 4 12
4 1 2 2
5 2 1 1
In this case, if we want to have 11, we will take the two first column + the third and we will change the number to have a coherent value.
So the result awaited :
ID IDREF NUMBER SUM
1 1 5 5
2 1 3 8
3 1 3 11
Please note the change in the third line on the NUMBER and SUM column.
Do you know how to achieve that ?
This query should work from sql 2000 to 2008 R2
I've created a solution here which uses a view: http://www.sqlfiddle.com/#!3/ebb01/15
The view contains a running total column for each IDRef:
CREATE VIEW MouvementsRunningTotals
AS
SELECT
A.ID,
A.IDRef,
MAX(A.Number) Number,
SUM (B.Number) RunningTotal
FROM
Mouvements A
LEFT JOIN Mouvements B ON A.ID >= B.ID AND A.IDRef = B.IDRef
GROUP BY
A.ID,
A.IDRef
If you can't create a view then you could create this as a temporary table in tsql.
Then the query is a self join on that view, in order to determine which is the last row to be include based on the Number you pass in. Then a CASE statement ensures the correct value for the last row:
DECLARE #total int
DECLARE #idRef int
SELECT #total = 4
SELECT #idRef = 1
SELECT
A.ID,
A.IDRef,
CASE
WHEN A.RunningTotal <= #total THEN A.Number
ELSE #total - B.RunningTotal
END Number
FROM
MouvementsRunningTotals A
LEFT JOIN MouvementsRunningTotals B ON
A.IDRef = B.IDRef
AND A.RunningTotal - A.Number = B.RunningTotal
WHERE
A.IDRef = #IDRef
AND (A.RunningTotal <= #total
OR (A.RunningTotal > #total AND B.RunningTotal < #total))
You can add more data in the Build Schema box and change the Number in the #total parameter in the Query box to test it.
select id, (select top 1 number from mouvements) as number, idref
from mouvements where idref=1 order by id asc