Multiple random values in SQL Server 2005 - sql

I need to generate multiple random values under SQL Server 2005 and somehow this simply wont work
with Random(Value) as
(
select rand() Value
union all
select rand() from Random
)select top 10 * from Random
Whats the preffered workaround?

have you tries something like this (found at http://weblogs.sqlteam.com ) :
CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber
GO
create a function
CREATE FUNCTION RandNumber()
RETURNS float
AS
BEGIN
RETURN (SELECT RandNumber FROM vRandNumber)
END
GO
then you can call it in your selects as normal
Select dbo.RandNumber() , * from myTable
or from their comments:
select RAND(CAST(NEWID() AS BINARY(6))), * from myTable

I'm currently using this:
with Random(Value) as
(
select rand(checksum(newid())) Value
union all
select rand(checksum(newid())) from Random
)select top 10 * from Random
but that seems overly hackish :S
Why doesnt rand get reevaluated in the first version?

Related

Applying the TOP keyword to an INTERSECTion in Transact-SQL

I'm working on a project that requires many INTERSECTions and uses a pretty large database, so I'd love to be able to apply TOP to my queries to make things not-so-slow.
Problem is, I know you can do something like (pseudocode-y but I hope it's understandable):
(SELECT TOP 50 * FROM A) INTERSECT (SELECT TOP 50 * FROM B); GO
BUT
can you do something along these lines in some way?
SELECT TOP 50 (SELECT * FROM A INTERSECT SELECT * FROM B); GO
You can write it as:
SELECT TOP 50 * from (SELECT * FROM A INTERSECT SELECT * FROM B) x; GO

SQL "WITH" to include multiple derived tables

Can I write something like below. But this is not giving proper output in WinSQL/Teradata
with
a (x) as ( select 1 ),
b (y) as ( select * from a )
select * from b
Do you really need to use CTEs for this particular solution when derived tables would work as well:
SELECT B.*
FROM (SELECT A.*
FROM (SELECT 1 AS Col1) A
) B;
That being said, I believe multiple CTEs are available in Teradata 14.10 or 15. I believe support for a single CTE and the WITH clause were introduced in Teradata 12 or 13.
You call the dependent 1st and then the parent
like this and it will work. Why is it like that ? Teradata likes people to play with it longer and spend more time with it, making it feel important
with
"b" (y) as ( select * from "a" ),
"a" (x) as ( select '1' )
select * from b

How can I select rows by range? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Select statement in SQLite recognizing row number
For example, SELECT * FROM table WHERE [row] BETWEEN x AND y
How can this be done? I've done some reading but haven't found anything specifically correct.
Imagine a list where you want results paged by an X amount of results, so for page 10 you would need results from rows 10 * X to 10 * X + X. Rather than display ALL results in one go
For mysql you have limit, you can fire query as :
SELECT * FROM table limit 100` -- get 1st 100 records
SELECT * FROM table limit 100, 200` -- get 200 records beginning with row 101
For Oracle you can use rownum
See mysql select syntax and usage for limit here.
For SQLite, you have limit, offset. I haven't used SQLite but I checked it on SQLite Documentation. Check example for SQLite here.
Following your clarification you're looking for limit:
SELECT * FROM `table` LIMIT 0, 10
This will display the first 10 results from the database.
SELECT * FROM `table` LIMIT 5, 5 .
Will display 5-9 (5,6,7,8,9)
The syntax follows the pattern:
SELECT * FROM `table` LIMIT [row to start at], [how many to include] .
The SQL for selecting rows where a column is between two values is:
SELECT column_name(s)
FROM table_name
WHERE column_name
BETWEEN value1 AND value2
See: http://www.w3schools.com/sql/sql_between.asp
If you want to go on the row number you can use rownum:
SELECT column_name(s)
FROM table_name
WHERE rownum
BETWEEN x AND y
However we need to know which database engine you are using as rownum is different for most.
You can use rownum :
SELECT * FROM table WHERE rownum > 10 and rownum <= 20
Using Between condition
SELECT *
FROM TEST
WHERE COLUMN_NAME BETWEEN x AND y ;
Or using Just operators,
SELECT *
FROM TEST
WHERE COLUMN_NAME >= x AND COLUMN_NAME <= y;
Assuming id is the primary key of table :
SELECT * FROM table WHERE id BETWEEN 10 AND 50
For first 20 results
SELECT * FROM table order by id limit 20;
Have you tried your own code?
This should work:
SELECT * FROM people WHERE age BETWEEN x AND y
Use the LIMIT clause:
/* rows x- y numbers */
SELECT * FROM tbl LIMIT x,y;
refer : http://dev.mysql.com/doc/refman/5.0/en/select.html

SQL Return Random Numbers Not In Table

I have a table with user_ids that we've gathered from a streaming datasource of active accounts. Now I'm looking to go through and fill in the information about the user_ids that don't do much of anything.
Is there a SQL (postgres if it matters) way to have a query return random numbers not present in the table?
Eg something like this:
SELECT RANDOM(count, lower_bound, upper_bound) as new_id
WHERE new_id NOT IN (SELECT user_id FROM user_table) AS user_id_table
Possible, or would it be best to generate a bunch of random numbers with a scripted wrapper and pass those into the DB to figure out non existant ones?
It is posible. If you want the IDs to be integers, try:
SELECT trunc((random() * (upper_bound - lower_bound)) + lower_bound) AS new_id
FROM generate_series(1,upper_bound)
WHERE new_id NOT IN (
SELECT user_id
FROM user_table)
You can wrap the query above in a subselect, i.e.
SELECT * FROM (SELECT trunc(random() * (upper - lower) + lower) AS new_id
FROM generate_series(1, count)) AS x
WHERE x.new_id NOT IN (SELECT user_id FROM user_table)
I suspect you want a random sampling. I would do something like:
SELECT s
FROM generate_series(1, (select max(user_id) from users) s
LEFT JOIN users ON s.s = user_id
WHERE user_id IS NULL
order by random() limit 5;
I haven't tested this but the idea should work. If you have a lot of users and not a lot of missing id's it will perform better than the other options, but performance no matter what you do may be a problem.
My pragmatic approach would be: generate 500 random numbers and then pick one which is not in the table:
WITH fivehundredrandoms AS ( RANDOM(count, lower_bound, upper_bound) AS onerandom
FROM (SELECT generate_series(1,500)) AS fivehundred )
SELECT onerandom FROM fivehundredrandoms
WHERE onerandom NOT IN (SELECT user_id FROM user_table WHERE user_id > 0) LIMIT 1;
There is way to do what you want with recursive queries, alas it is not nice.
Suppose that you have the following table:
CREATE TABLE test (a int)
To simplify, you want to insert random numbers from 0 to 4 (random() * 5)::int that are not in the table.
WITH RECURSIVE rand (i, r, is_new) AS (
SELECT
0,
null,
false
UNION ALL
SELECT
i + 1,
next_number.v,
NOT EXISTS (SELECT 1 FROM test WHERE test.a = next_number.v)
FROM
rand r,
(VALUES ((random() * 5)::int)) next_number(v)
-- safety check to make sure we do not go into an infinite loop
WHERE i < 500
)
SELECT * FROM rand WHERE rand.is_new LIMIT 1
I'm not super sure, but PostgreSQL should be able to stop iterating once it has one result, since it knows that the query has limit 1.
Nice thing about this query is that you can replace (random() * 5)::int with any id generating function that you want

select top 1 * returns diffrent recordset each time

In my application I use SELECT TOP 12 * clause to select top 12 records from database and show it to user. In another case I have to show the same result one by one. So I use SELECT TOP 1 * clause,rest of the query is same. I used Sql row_number() function to select items one by on serially.
The problem is SELECT TOP 1 * doesn't return me same row as I get in SELECT TOP 12 *. Also the result set of SELECT TOP 12 * get changed each time I execute the query.
Can anybody explain me why the result is not get same in SELECT TOP 12 * and SELECT TOP 1 *.
FYI: here is my sql
select distinct top 1 * from(
select row_number() over ( ORDER BY Ratings desc ) as Row, * from(
SELECT vw.IsHide, vw.UpdateDate, vw.UserID, vw.UploadPath, vw.MediaUploadID, vw.Ratings, vw.Caption, vw.UserName, vw.BirthYear, vw.BirthDay, vw.BirthMonth, vw.Gender, vw.CityProvince, vw.Approved
FROM VW_Media as vw ,Users as u WITH(NOLOCk)
WHERE vw.IsHide='false' and
GenderNVID=5 and
vw.UserID=u.UserID and
vw.UserID not in(205092) and
vw.UploadTypeNVID=1106 and
vw.IsDeleted='false' and
vw.Approved = 1 and
u.HideProfile=0 and
u.StatusNVID=126 and
vw.UserID not in(Select BlockedToUserID from BlockList WITH(NOLOCk) where UserID=205092) a) totalres where row >0
Thanks in Advance
Sachin
When you use SELECT TOP, you must use also the ORDER BY clause to avoid different results every time.
For performance resons, the database is free to return the records in any order it likes if you don't specify any ordering.
So, you always have to specify in which order you want the records, if you want them in any specific order.
Up to some version of SQL Server (7 IIRC) the natural order of the table was preserved in the result if you didn't specify any ordering, but this feature was removed in later versions.