Related
I am trying to build subpartitioned table with CTAS from non-partitioned table but I got errors. How can I do that.Here is similiar example for my data ID IS PRIMARY KEY:
TASK
ID START_DATE
1 22/09/21
2 21/09/21
3 20/09/21
And Here is my code :
CREATE TABLE EMPLOYEE AS
(SELECT * FROM TASK)
PARTITION BY RANGE ("START_DATE")
SUBPARTITION BY LIST("ID")
PARTITION P1 VALUES LESS THAN TO_DATE('20210920','YYYYYMMDD') (
SUBPARTITION S1 VALUES (1),
SUBPARTITION S2 VALUES (2),
SUBPARTITION S3 VALUES (3)
),
PARTITION P2 VALUES LESS THAN TO_DATE('20210921','YYYYYMMDD') (
SUBPARTITION S4 VALUES (1),
SUBPARTITION S5 VALUES (2),
SUBPARTITION S6 VALUES (3)
),
PARTITION P3 VALUES LESS THAN TO_DATE('20210922','YYYYYMMDD') (
SUBPARTITION S7 VALUES (1),
SUBPARTITION S8 VALUES (2),
SUBPARTITION S9 VALUES (3)
),
PARTITION P4 VALUES LESS THAN MAXVALUE (
SUBPARTITION S10 VALUES (1),
SUBPARTITION S11 VALUES (2),
SUBPARTITION S12 VALUES (3)
)
How can I do that it is important for me I am getting this error and I think I will get another errors when I correct it:
00933. 00000 - "SQL command not properly ended"
An example
SQL> create table task ( id number , start_date date ) ;
Table created.
SQL> CREATE TABLE t2
2 PARTITION BY RANGE (START_DATE)
3 SUBPARTITION BY LIST (ID)
4 (
5 PARTITION P1 VALUES LESS THAN (TO_DATE('2021-07-20','YYYY-MM-DD'))
6 (
7 SUBPARTITION S1 VALUES (1),
8 SUBPARTITION S2 VALUES (2),
9 SUBPARTITION S3 VALUES (3)
10 ),
11 PARTITION P2 VALUES LESS THAN (TO_DATE('2021-08-20','YYYY-MM-DD'))
12 (
13 SUBPARTITION S4 VALUES (1),
14 SUBPARTITION S5 VALUES (2),
15 SUBPARTITION S6 VALUES (3)
16 )
17 )
18* as select * from task
SQL> /
Table created.
Considerations
Use the expression as select * from xxx at the end of the construction.
Keep in mind the parenthesis for each partition and subpartition construction.
Although I did not put it on my example, try to use a subpartition template.
I would recommend an INTERVAL partition and subpartition template. Would be this one:
CREATE TABLE EMPLOYEE (
...
)
PARTITION BY RANGE (START_DATE) INTERVAL (INTERVAL '1' DAY)
SUBPARTITION BY LIST (ID)
SUBPARTITION TEMPLATE (
SUBPARTITION S1 VALUES (1),
SUBPARTITION S2 VALUES (2),
SUBPARTITION S3 VALUES (3)
)
( PARTITION P_INITIAL VALUES LESS THAN (TIMESTAMP '2021-09-01 00:00:00') SEGMENT CREATION DEFERRED );
Here's the thing, I have a table looking like this:
col1 col2 col3
A {"0":10, "5":5, "15":3} 6
B {"5":30, "10":20, "15":10, "20":5} 15
C {"0":30, "3":20, "8":10, "9":5} 2
.
.
.
col2 is basically a rank (number between quotes) and a grade; col3 is the rank for each customer (defined in col1). So if the customer A is ranked 0-4, his grade is 10, if he's ranked 5-14, his grade is 5, otherwise is 3.
I need to create a new column by getting the grade corresponding to the rank defined in col3.
This is what the final result would look like:
col1 col2 col3 col4
A {"0":10, "5":5, "15":3} 5 5
B {"5":30, "10":20, "15":10, "20":5} 13 20
C {"0":30, "3":20, "8":10, "9":5} 2 30
.
.
.
Any ideas? I thought about split_part(), but I don't think I can make this work, even by putting many case when (not sure, couldn't think of a solution).
You may find the below approach useful.
Unfortunately, Redshift has less amount of needed functions comparing to PostgreSQL (which it is based on).
That's why I had to apply some workaround - table "number_sequence", which is used to extract grades from customer JSONs. It is necessary to populate this table with sequential numbers up to the value of maximum rank, presented in customer JSON dictionaries. Also, since I dont have access to Redshift I have tested the solution only in PostgreSQL. So it might be nessecary to made some tailoring to Redshift environment. Have a good luck! :)
CREATE TABLE number_sequence (
num int
);
INSERT INTO number_sequence (num)
SELECT * FROM (VALUES
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(10), (11), (12), (13), (14), (15), (16), (17), (18), (19),
(20), (21), (22), (23), (24), (25), (26), (27), (28), (29)
) num_sec;
CREATE TABLE customer_rank_grade (
col1 varchar,
col2 varchar,
col3 int
);
INSERT INTO customer_rank_grade (col1, col2, col3)
select * from
(values
('A', '{"0":10, "5":5, "15":3}', 5),
('B', '{"5":30, "10":20, "15":10, "20":5}', 13),
('C', '{"0":30, "3":20, "8":10, "9":5}', 2)
) data;
WITH selected_rank as (
SELECT
col1,
col2,
col3,
json_extract_path_text(col2::json, num::varchar) as col4,
ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY num DESC) as row_num
FROM number_sequence
JOIN customer_rank_grade
ON json_extract_path_text(col2::json, num::varchar) IS NOT NULL
WHERE num <= col3
)
SELECT
col1, col2, col3, col4
FROM selected_rank
WHERE row_num = 1
ORDER BY col1;
I am getting the above error, and it hits on my Insert on line 95:
"INSERT INTO #total"
I added the columns topic_name varchar(100), samplegroup_name varchar (50), subtopic varchar(50)
from a working query, and that caused the error. None of these columns are Floats, the above types are correct. If I comment out those columns then the query runs fine, so I'm not really sure what to do from here.
You have an issue with the order of the values you try to insert into #total.
Look at the definition of #total:
DECLARE #total TABLE (
item_id varchar (30),
item_dbkey int,
status varchar (7),
nT float,
nY float ,
sigmaX float,
sigmaSqX float,
sigmaY float,
topic_name varchar(100),
samplegroup_name varchar (50),
subtopic varchar(50)
)
and now note the insertion:
INSERT INTO #total
SELECT
Item_id,
CTR.item_dbkey,
TIP.Status,
tpta.topic_name, -- this tries to go into nT
ttisg.samplegroup_name, -- this tries to go into nY
TIP.subtopic, -- this tries to go into sigmaX
COUNT(CTR.item_dbkey), -- Number of exams which had this item_dbkey
COUNT(CASE WHEN iop.weightage >= 1 THEN CTR.item_dbkey END) C, -- How many times was this answered correctly
SUM (CTAP.raw_score ) AS totalscore, -- Sum of all scores (scaled or raw)
SUM (SQUARE( CTAP.raw_score ) ) AS totalscore2, -- Sum of the Square of all scores (scaled or raw)
SUM (CASE WHEN iop.weightage >= 1 THEN ( CTAP.raw_score ) END ) AS totalscorecorr -- When answered correctly, sum the scores (scaled or raw)
topic_name, for example, cannot be inserted into nT column!
I have a simple table named HotelRate
HID | START_DATE | END_DATE | PRICE_PER_DAY
--------------------------------------
1 01/1/2015 10/1/2015 100
1 11/1/2015 20/1/2015 75
1 21/1/2015 30/1/2015 110
what is the most simple way to calculate price for Hotel Room if user queries for Total Price between 5/1/2015 to 25/1/2015.
I have checked :
How can I query for overlapping date ranges?
Overlapping date range MySQL
but none of it is making much sense to me.
I have tried a couple queries but those seems like hitting arrow in the blind. Can someone suggest me a simple and elegant way to do it ?
#JamesZ
On running the first query i get
start_date end_date duration price_per_day
---------- ---------- ----------- -------------
2015-01-01 2015-01-10 5 100
2015-01-11 2015-01-20 9 75
2015-01-21 2015-01-30 4 110
For first range 5 is OK, second range it should be 10, third be 5
How days are calculated : Total no of nights between start & end date, which is same as days difference
05-Jan-15 06-Jan-15 1 Night
06-Jan-15 07-Jan-15 1 Night
07-Jan-15 08-Jan-15 1 Night
08-Jan-15 09-Jan-15 1 Night
09-Jan-15 10-Jan-15 1 Night
10-Jan-15 11-Jan-15 1 Night
11-Jan-15 12-Jan-15 1 Night
12-Jan-15 13-Jan-15 1 Night
13-Jan-15 14-Jan-15 1 Night
14-Jan-15 15-Jan-15 1 Night
15-Jan-15 16-Jan-15 1 Night
16-Jan-15 17-Jan-15 1 Night
17-Jan-15 18-Jan-15 1 Night
18-Jan-15 19-Jan-15 1 Night
19-Jan-15 20-Jan-15 1 Night
20-Jan-15 21-Jan-15 1 Night
21-Jan-15 22-Jan-15 1 Night
22-Jan-15 23-Jan-15 1 Night
23-Jan-15 24-Jan-15 1 Night
24-Jan-15 25-Jan-15 1 Night
Count : 20 Night
Something like this should do the trick:
declare #startdate date, #enddate date
set #startdate = '20150105'
set #enddate = '20150125'
select
start_date,
end_date,
datediff(
day,
case when #startdate > start_date then #startdate else start_date end,
case when #enddate < end_date then #enddate else end_date end) as duration,
price_per_day
from
reservation
where
end_date >= #startdate and
start_date <= #enddate
This just handles the overlapping ranges with case so that if the reservation start is the correct one to use, it takes it, otherwise the search criteria, and same thing for end date. The days and price are here separate, but you can just multiply them to get the result.
SQL Fiddle: http://sqlfiddle.com/#!3/4027b3/1
Edit, this way to get total sum:
declare #startdate date, #enddate date
set #startdate = '20150105'
set #enddate = '20150125'
select
sum(datediff(
day,
case when #startdate > start_date then #startdate else start_date end,
case when #enddate < end_date then #enddate else end_date end)
* price_per_day)
from
reservation
where
end_date >= #startdate and
start_date <= #enddate
You will need a calendar table, but every database should have one.
The actual implementation is always user and DBMS specific (e.g. MS SQL Server), so searching for "calendar table" + yourDBMS will probably reveal some source code for your system.
select HID, sum(PRICE_PER_DAY)
from calendar_table as c
join HotelRate
on calendar_date between START_DATE and END_DATE
group by HID
This is easy to handle if you have an existing table of dates to work with. Don't have one already? Below you'll find two functions to help you get started. This is how you use them:
-- Arguments can be passed in any order
SELECT * FROM dbo.RangeDate('2015-12-31', '2015-01-01');
SELECT * FROM dbo.RangeSmallInt(10, 0);
SELECT A.HID, SUM(A.PRICE_PER_DAY)
FROM dbo.RangeDate('2000-01-01', '2020-12-31') Calendar
JOIN HotelRate A
ON Calendar.D BETWEEN A.START_DATE and A.END_DATE
GROUP BY A.HID;
You can use the RangeDate function as a calendar or you can use it to build your own calendar function/table.
-- Generate a range of up to 65,536 contiguous DATES
CREATE FUNCTION dbo.RangeDate (
#date1 DATE = NULL
, #date2 DATE = NULL
)
RETURNS TABLE
AS
RETURN (
SELECT D = DATEADD(DAY, A.N, CASE WHEN #date1 <= #date2 THEN #date1 ELSE #date2 END)
FROM dbo.RangeSmallInt(
CASE WHEN #date1 IS NOT NULL AND #date2 IS NOT NULL THEN 0 END
, ABS(DATEDIFF(DAY, #date1, #date2))
) A
);
-- Generate a range of up to 65,536 contiguous BIGINTS
CREATE FUNCTION dbo.RangeSmallInt (
#n1 BIGINT = NULL
, #n2 BIGINT = NULL
)
RETURNS TABLE
AS
RETURN (
WITH Numbers AS (
SELECT N FROM(VALUES
(1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
) V (N)
)
SELECT TOP (
CASE
WHEN #n1 IS NOT NULL AND #n2 IS NOT NULL THEN ABS(#n2 - #n1) + 1
ELSE 0
END
)
N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1 + CASE WHEN #n1 <= #n2 THEN #n1 ELSE #n2 END
FROM Numbers A, Numbers B
WHERE ABS(#n2 - #n1) + 1 < 65537
);
You can use this which will work out the price per period and then sum it up for the total cost. It uses a case statement to work out how many days are in each period so in your example this is 5,9 and 4:
Declare #startdate date = '2015-01-05',
#todate date = '2015-01-25'
Select sum(price_per_period) as TotalPrice -- The cost for all periods is summed to give a total
from
-- First it works out the number of days in the period with a case statement and then
-- multiplies this by the daily rate to get the total for that period
(Select price_per_day * case when Start_date <= #startdate then DATEDIFF(day, #startdate,end_date) else
case when Start_date > #startdate and end_date < #todate then DATEDIFF(day, start_date,end_date) else
case when Start_date > #startdate and end_date >= #todate then DATEDIFF(day, start_date, #todate) end
end
end price_per_period
from pricetable
where (Start_date between #Startdate and #todate) or
(end_date between #Startdate and #todate)
) a
This eliminates the need for a seperate calendar table
SQL Fiddle: http://www.sqlfiddle.com/#!6/25e63/4/0
This should be fast enough as you first generate calendar and then using only join. Also for total price per hotel could be achieved with grouping sets:
Data definition:
create table HotelRate(HID int, START_DATE date, END_DATE date, PRICE_PER_DAY int);
insert into HotelRate values
(1, '20150101', '20150110', 100),
(1, '20150111', '20150120', 75),
(1, '20150121', '20150130', 110),
(2, '20150101', '20150110', 10),
(2, '20150111', '20150120', 5),
(2, '20150121', '20150130', 50)
Query:
declare #sd date = '20150105' , #ed date = '20150125'
;with c as(select #sd d union all select dateadd(dd, 1, d) from c where d < #ed)
select h.HID, h.START_DATE, h.END_DATE, sum(PRICE_PER_DAY) PRICE
from c join HotelRate h on c.d >= h.START_DATE and c.d < h.END_DATE
group by grouping sets((h.HID, h.START_DATE, h.END_DATE),(h.HID))
Output:
HID START_DATE END_DATE PRICE
1 2015-01-01 2015-01-10 500
1 2015-01-11 2015-01-20 675
1 2015-01-21 2015-01-30 550
1 (null) (null) 1725
2 2015-01-01 2015-01-10 50
2 2015-01-11 2015-01-20 45
2 2015-01-21 2015-01-30 250
2 (null) (null) 345
This can be further optimized with tally tables. And even more, if you create calendar table in your database, it will be instant.
Here is the fiddle http://sqlfiddle.com/#!3/25e7bc/1
Suppose you have created some calendar table Calendar(d date) which contains dates starting from for instance 1900-01-01 ending 2100-01-01. Add indexes on Calendar and HotelRange tables on date columns. Then above query can be rewritten as:
select h.HID, h.START_DATE, h.END_DATE, sum(PRICE_PER_DAY) PRICE
from Calendar c join HotelRate h on c.d >= h.START_DATE and c.d < h.END_DATE
where c.d between #sd and #ed
group by grouping sets((h.HID, h.START_DATE, h.END_DATE),(h.HID))
I have to get date repeatedly for every N months.
I have XDate to Start from.
I want the nth week's mth weekday's date.
N is say 2 - I have to get for every 2 month
XDate is suppose tomorrow's date. So, Starting from tomorrow
m is 7 - So, get date of every Saturday
n is 2 - of second week.
I could not even think for start point for this complex logic.
Any suggestion how should I start - pseudo code
Thanks in advance,
First, this is where a calendar table comes in handy. The following code creates a table called calendar and populates it with dates starting in 2000. It also has a column called NthWeekdayInMonth. For example, if you look at the entries for 1/29/05 through 1/31/05 you'll see that this column is set to a 5 because those were the 5th Saturday, Sunday, and Monday of the month.
CREATE TABLE Calendar
(
[Date] date NOT NULL,
[NthWeekdayInMonth] int,
CONSTRAINT PK_Calendar
PRIMARY KEY CLUSTERED ([Date])
WITH FILLFACTOR = 100
)
;WITH cte AS
(
SELECT
DATEADD(d, (a.Number * 256) + b.Number, '01/01/2000') AS [Date]
FROM
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) a (Number),
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) b (Number)
)
INSERT INTO Calendar
SELECT
[Date],
ROW_NUMBER() OVER (PARTITION BY YEAR([Date]), MONTH([Date]), DATEPART(dw, [Date]) ORDER BY [Date]) FROM cte
ORDER BY
[Date]
GO
Now that we have a calendar table the rest is fairly straightforward. I did deviate from your design in one respect but you should be able to adjust it if needed. In my implementation, the starting date is literally the first date that should be returned. So a starting date of 1/11/2014, looking every 2 months would return:
2014-01-11
2014-03-08
2014-05-10
2014-07-12
By passing the first date the code can figure out what day of the week it was and what week of the month. Passing those values in is redundant. The test code is below...
DECLARE #startDate date
DECLARE #everyNMonths int
DECLARE #numResults int
DECLARE #nthAppearanceOfDay int
SET #startDate = '01/11/2014' -- First occurence is on this date
SET #everyNMonths = 2 -- Skip every n months
SET #numResults = 4 -- Max # of results to return
-- Figure out which x-day of the month this is. For example, if the starting
-- date is 1/11/2014 that was the second Saturday so this will be set to 2.
SELECT #nthAppearanceOfDay = NthWeekdayInMonth FROM calendar WHERE [date] = #startDate
-- Use a CTE to get all the months involved in this calculation
;WITH candidateMonths AS (
SELECT
1 AS [resultnum], #startDate AS [date]
UNION ALL
SELECT resultnum + 1, DATEADD(month, #everyNMonths, [date]) FROM candidateMonths
WHERE resultnum + 1 <= #numResults
)
-- Now evaluate every date for each of the candidate months. If the day of week matches
-- that of the start date AND it is the Nth occurrence of that day of week in the month
-- include it
SELECT
c.[Date]
FROM
candidateMonths cm
INNER JOIN calendar c ON ( (YEAR(c.[Date]) = YEAR(cm.[Date])) AND (MONTH(c.[Date]) = MONTH(cm.[Date])))
WHERE
(DATEPART(dw, c.[date]) = DATEPART(dw, #startDate)) -- Same day of week
AND
(c.NthWeekdayInMonth = #nthAppearanceOfDay) -- Same week of month
I've been experimenting with the following code:
SELECT * FROM dbo.NthWeekday(GETDATE(), 1, 1);
SELECT * FROM dbo.NthWeekday(GETDATE(), 1, -1);
Where 1 is Sunday and 7 is Saturday regardless of the ##DATEFIRST setting. A positive value for n (or 0) will return the Next Nth Weekday while a negative value for n returns the Previous Nth Weekday.
I don't fully understand what you want but if I gathered correctly: just getting the Nth Weekday is not enough. You want to do this repeatedly for X months as well. This is the tentative code I'd use:
DECLARE #date DATE = GETDATE();
DECLARE #numMonths INT = -5
DECLARE #weekday INT = 1;
DECLARE #n INT = 2;
SELECT C.D
FROM dbo.RangeSmallInt(0, #numMonths - SIGN(#numMonths)) A
CROSS APPLY ( -- MonthBegin
SELECT DT = DATEADD(m, DATEDIFF(m, 0, #date) + A.N, 0)
) B
CROSS APPLY dbo.NthWeekday(B.DT, #weekday, #n) C;
Results: 2014-12-14
2015-01-11
2015-02-08
2015-03-08
2015-04-12
Which you could wrap in a table-valued function much like I have done with NthWeekday and RangeSmallInt. The RangeSmallInt function call can be replaced with a numbers table, tally CTE, or whatever terminology/style you're comfortable with.
How it works:
We start by generating a set of numbers beginning with 0 because we want the function to be inclusive. (#numMonths - SIGN(#numMonths)) handles the addition or subtraction of 1/0 from #numMonths based on the sign of #numMonths. This ensures that the proper range of integers (in the above case: 0 through -4) are generated for our next trick.
Once we have a range of integers to work with we can use them to offset the date. In this case we want to find out the beginning of the month for X months. If we had a function that could return the Nth Month Begin Date then we would simply pass the integers we already have to the function and get out the dates we want. So that's exactly what we do using CROSS APPLY.
Now that we have the beginning of the month for X months solved all we need to do is apply our NthWeekday function to these dates.
Nth Weekday:
CREATE FUNCTION dbo.NthWeekday (
#date DATE = NULL
, #weekday INT = NULL
, #n INT = 1
)
RETURNS TABLE
AS
RETURN (
SELECT D = CASE SIGN(#n)
WHEN -1 THEN DATEADD(d, -(DATEPART(dw, #date) + ##DATEFIRST - #weekday) % 7 + ((#n + 1) * 7), #date)
ELSE DATEADD(d, (#weekday - DATEPART(dw, #date) + ##DATEFIRST) % 7 + ((#n - SIGN(#n)) * 7), #date)
END
);
RangeSmallInt:
-- Generate a range of up to 65,536 contiguous BIGINTS
CREATE FUNCTION dbo.RangeSmallInt (
#num1 BIGINT = NULL
, #num2 BIGINT = NULL
)
RETURNS TABLE
AS
RETURN (
WITH Numbers(N) AS (
SELECT N FROM(VALUES
(1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
) V (N)
)
SELECT TOP (
CASE
WHEN #num1 IS NOT NULL AND #num2 IS NOT NULL THEN ABS(#num1 - #num2) + 1
ELSE 0
END
)
N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN #num1 <= #num2 THEN #num1 ELSE #num2 END - 1
FROM Numbers A
, Numbers B
WHERE ABS(#num1 - #num2) + 1 < 65537
);