sql table random numbers into multiple columns - sql

new here - but would appreciate any help
I have a table with one column - this column has numbers from 1 to 1000
I would like to break this column up into ten columns - so I would have 10 columns and 100 rows in my new table
I would also like the numbers to be in random order
Any help would really be appreciated -- thanks in advance

You can use conditional aggregation and row_number():
select max(case when seqnum % 10 = 0 then number end) as number_1,
max(case when seqnum % 10 = 1 then number end) as number_2,
. . .
max(case when seqnum % 10 = 9 then number end) as number_10
from (select t.*,
row_number() over (order by newid()) - 1 as seqnum
from t
) t
group by floor(seqnum / 10)

Related

SQL Splitting dataset into 3 sections 60/20/20 for testing

I have a dataset that I want to split into 3 groups and the splits to be 60/20/20. I would also like the split to be random. Was wondering what is the best method to do this using SQL (redshift). I tried using percent rank but that doesn't work so open to ideas.
Thanks.
Example data:
ID
Column 2
123214123
Y
544354342
N
43241231
Y
231213123
Y
123123123
Y
The simplest method is probably just using random():
select t.*,
(case when random() < 0.6 then 'group1'
when random() < 0.5 then 'group2'
else 'group3'
end)
from t;
This is only approximate in the counts. You can get more precision using window functions:
select t.*,
(case when ntile <= 6 then 'group1'
when ntile <= 8 then 'group2'
else 'group3'
end)
from (select t.*,
ntile(10) over (order by random()) as tile
from t
) t

SQL help to insert unique values

I need to insert the Unique combination of Ticker, Dividend_Pay_Date to another table. If I find duplicate data I need to select only the Dividend_type_marker_description = 'Final' row. I am showing example of source data where I have duplicate data for Ticker ABC.
I have noticed Dividend_type_marker_description = '2nd Interim' also for same date-ticker combination. But no more than 3 status
I would appreciate any help with this.
I think row_number() does what you want:
select . . .
from (select t.*,
row_number() over (partition by ticker, dividend_pay_rate
order by (case when Dividend_type_marker_description = 'Final' then 1 else 2 end)
) as seqnum
from t
) t
where seqnum = 1;

Calculate lead-time between selected rows (SQL)

Given this table where we have users, the product that they used, and the first date that they used the product (I have also created a simple rank by user window). Note, each user will only have minimum 0 rows if they used nothing before, and 2 rows, if they used both products. There are only 3 products - cigars and beers.
How can I create a new view where each row is 1 user, the next column shows the first product, the next column shows the 2nd product, and the last column shows the lead-time b/w the first dates of use?
One method is conditional aggregation with row_number():
select user,
max(case when seqnum = 1 then product end) as product_1,
max(case when seqnum = 2 then product end) as product_2,
(max(case when seqnum = 2 then time_used end) -
max(case when seqnum = 1 then time_used end)
) as dif
from (select t.*,
row_number() over (partition by user order by time_used) as seqnum
from t
) t
group by user;
Date/time functions vary significantly across different databases. Not all support a simple -, so you might nee to adjust for your database.
Minus between dates may not work on each database
select
c1.user_id,
c1.first_product_used,
c2.second_product_used,
COALESCE(CAST((Cast(c2.second_date AS DATE) - Cast(c1.first_date AS DATE)) AS VARCHAR(20)), 'n/a') AS "leadtime_days"
from
(
select
user_id,
product_used AS first_product_used,
time_used AS first_date
from
check2
where
rank_of_use = 1
)c1
LEFT OUTER JOIN
(
select
user_id,
product_used AS second_product_used,
time_used AS second_date
from
check2
where
rank_of_use = 2
)c2
ON
c1.user_id = c2.user_id

select every top 1 row and 100th row value from table with 10000 rows

I have a table that has 10000 plus rows. I am trying to select the value of every top 1 and top 100th row that has where clause and dividing the table by 100 in the loop.
Ex is shown in the screenshot
I think something like this:
select t.refid, lead(t.refid) over (order by refid) as next_refid
from (select t.*,
row_number() over (order by refid) - 1 as seqnum
from t
) t
where seqnum % 100 = 0

SQL Group up rows data into one row

I have data in a table like this:
I want to organise the table data so that I can get a maximum of 3 letters per row grouped by account number.
Below would be the result I want:
I can use dense rank to group up the account numbers but not sure how to get the data I want in the format above.
Logic:
There are 4 letters for account 123. Final result groups by account number with first 3 letters as you can only have a maximum of 3 letters per row. The fourth letter must go on the second row.
Here's one option using conditional aggregation, first creating a row_number, and then creating a row grouping using every 3 rows with % (modulus operator):
select account_number,
max(case when rn % 3 = 1 then letter end) as letter1,
max(case when rn % 3 = 2 then letter end) as letter2,
max(case when rn % 3 = 0 then letter end) as letter3
from (
select *, row_number() over (partition by account_number, rn % 3 order by rn) newrn
from (
select *, row_number() over (partition by account_number order by letter) rn
from yourtable
) t
) y
group by account_number, newrn
order by account_number
Online Demo
I would do this with only one call to row_number():
select account_number,
max(case when seqnum % 3 = 1 then letter end) as letter_a,
max(case when seqnum % 3 = 2 then letter end) as letter_b,
max(case when seqnum % 3 = 0 then letter end) as letter_c
from (select t.*,
row_number() over (partition by account_number order by letter) as seqnum
from t
) t
group by account_number, floor( (seqnum - 1) / 3)
order by account_number, min(seqnum);