Select Top N Random rows from table then ordering by column - sql

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

Related

SQL order groups of data

Here I have a data sample:
Title
Size
Count
First
3
14
First
5
3
Second
2
5
First
2
10
Third
3
10
Second
3
4
Third
2
9
Third
5
11
Second
5
4
Now I want to sort the data with following rules:
Put the records with same title together: First followed by First, Second followed by Second.
Then for each group, order them by size;
For groups, order them in the sum of count of each group, like: sum of First is 14+3+10=27, Second is 5+4+4=13, Third is 10+9+11=30.
The result I want:
Title
Size
Count
Second
2
5
Second
3
4
Second
5
4
First
2
10
First
3
14
First
5
3
Third
2
9
Third
3
10
Third
5
11
It's an easy sort once you get the total "Count" per Title.
A SUM OVER can be used for that.
SELECT
q.title AS "Title"
, q.size AS "Size"
, q.count AS "Count"
FROM
(
SELECT t.title, t.size, t.count
, SUM(t.count) OVER (PARTITION BY t.title) AS TotalCount
FROM yourtable t
) q
ORDER BY q.TotalCount, q.title, q.size
Title
Size
Count
Second
2
5
Second
3
4
Second
5
4
First
2
10
First
3
14
First
5
3
Third
2
9
Third
3
10
Third
5
11
Demo on db<>fiddle here
You can join the results of the group count sums back onto the main table, using the sums in the order by clause:
select t.* from tbl t join
(select t1.title, sum(t1.cnt) s from tbl t1 group by t1.title) t2
on t.title = t2.title order by t2.s, t.title, t.size;
Another approach is by using WITH Queries (Common Table Expressions)
with ct
as (
select title
,size
,count
,sum(count) over (partition by title) sm
from tbl
)
select title
,size
,count
from ct
order by ct.sm,2;

Find rows that contains same value on different columns

The table to find which rows contains same value on two different columns for 2 rows. Here is a small sample rows among 2k+ rows.
id left right
1 3 4
2 4 1
3 1 9
4 2 6
5 2 5
6 9 8
7 0 7
In the above case, I need to get row 1,2,3,6 as it contains 4 on two rows of two different columns i.e (id=1&2),1 on two rows of two different columns(id=1&3) and 9 on two rows of two different columns(id=3&6)
My thoughts:
I did thought many things for example cross join on left and right column, group by and count etc.
with Final as (With OuterTable as (WITH Alias AS (SELECT id as left_id , left FROM Test)
SELECT DISTINCT id, left_id FROM Alias
INNER JOIN Test ON Alias.left = Test.right)
SELECT id from OuterTable
UNION ALL
SELECT left_id from OuterTable)
SELECT DISTINCT * from Final;
It's messy, but it works.
You can do it with EXISTS:
SELECT t1.*
FROM tablename t1
WHERE EXISTS (
SELECT 1 FROM tablename t2
WHERE t1.id <> t2.id AND (t2.left = t1.right OR t1.left = t2.right)
)
See the demo.
Results:
id
left
right
1
3
4
2
4
1
3
1
9
6
9
8

Select 4 rows at random with minimum values in sqlite

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.

How do i select 4 rows from a table holding 10 rows of persons based on the youngest age?

Lets say i have a table containing these rows
id age
1 5
2 7
3 8
4 9
5 3
6 1
How do i write a select statement that selects exactly 4 of the youngest persons?
You would use top and order by:
select top (4) t.*
from t
order by age asc;
SELECT id, age
FROM [MyTable]
ORDER BY age
OFFSET 0 ROWS FETCH NEXT 4 ROWS ONLY

How to update a column with incrementally sequenced values that change depending on other column value

I am trying to update a column in a table so that the Index column (which is currently arbitrary numbers) is renumbered sequentially starting at 1000 with increments of 10, and this sequence restarts every time the Group changes.
I have tried ROWNUMBER() with PARTITION and trying to define a SEQUENCE, but I can't seem to get the result I'm looking for.
Table 1
ID Group Index
1 A 1
2 A 2
3 B 3
4 B 4
5 B 5
6 C 6
7 D 7
What I want:
Table 1
ID Group Index
1 A 1000
2 A 1010
3 B 1000
4 B 1010
5 B 1020
6 C 1000
7 D 1000
You can use row_number() with some arithmetic:
select t.*,
990 + 10 * row_number() over (partition by group order by id) as index
from t;
Note that group and index are SQL reserved words, so they are really bad column names.