Set field to random value from another table - sql-server

update table1
set firstname = (select top 1 firstname from table2 order by NEWID())
This just sets table1.firstname to the same value for all records. I know it's possible to do this, but everything I've seen online expects the same row count in both tables (or at least a greater amount in table1). I have 200,000 records in table1, I have 200 in table2. How can I set table1.firstname to a random value from table2.firstname when the row counts are off?

DECLARE #t1 TABLE (a INT)
DECLARE #t2 TABLE (b INT, c INT)
INSERT INTO #t1(a)
VALUES (0), (1), (2), (3), (4), (5)
INSERT INTO #t2(b)
VALUES (0), (1), (2)
UPDATE t2
SET c = t1.a
FROM #t2 t2
CROSS APPLY (
SELECT TOP(1) t1.a
FROM #t1 t1
WHERE t2.b IS NOT NULL -- any calculations for t2 columns
ORDER BY NEWID()
) t1
SELECT * FROM #t2
Output -
b c
----------- -----------
0 5
1 1
2 0

Related

Select query to get counts

I have 2 tables that I want to query against. If a record exists in both tables then count record and assign to Both, if record exist in Table 1 (T1 Only), then count it and assign to T1 Only, if record exists in Table 2 (T2 Only), then count it and assign to T2 Only column. Have the result set come out as follows.
Both T1 Only T2 Only
2000 3000 4000
Use a FULL JOIN. It will return all records from both tables in the query. See example below for your desired result.
CREATE TABLE #Table1 (Id INT);
CREATE TABLE #Table2 (Id INT);
INSERT INTO #Table1 VALUES (1), (2), (3), (4), (5), (6);
INSERT INTO #Table2 VALUES (3), (4), (5), (6), (7);
SELECT
SUM(CASE WHEN T1.Id IS NOT NULL AND T2.Id IS NOT NULL THEN 1 ELSE 0 END) AS Both
, SUM(CASE WHEN T1.Id IS NOT NULL AND T2.Id IS NULL THEN 1 ELSE 0 END) AS T1Only
, SUM(CASE WHEN T1.Id IS NULL AND T2.Id IS NOT NULL THEN 1 ELSE 0 END) AS T2Only
FROM #Table1 AS T1 FULL JOIN #Table2 AS T2 ON T2.Id = T1.Id;

Order by first row,last row and rest with 2 tables in SQL Server 2017

I have following two tables. I need to merge 2 tables based also sorted on
few conditions.
DROP TABLE IF EXISTS #t1
CREATE TABLE #t1
(
id INT IDENTITY PRIMARY KEY,
value INT
)
DROP TABLE IF EXISTS #t2
CREATE TABLE #t2
(
id INT IDENTITY PRIMARY KEY,
value int
)
INSERT INTO #t1 (value)
VALUES (1), (30), (19), (10), (40);
INSERT INTO #t2 (value)
VALUES (100), (70), (20);
SELECT * FROM #t1
UNION
SELECT * FROM #t2
I need to union 2 tables and sorted value based on below condition
#t1 first row (fixed)
#t1 last row (fixed)
#t1 rest (other than first row) based on value
4 #t2 only sorted based on value
Expected output:
why are you using varchar to store numeric value ? you will need to perform a cast() or convert() before you will be to sort it.
Assumption : by first or last you are referring with row with minimum and maximum value in column id.
select value, seq as [order]
from
(
select id, value,
seq = case when row_number() over(order by id) = 1 then 1
when row_number() over(order by id desc) = 1 then 2
else 3
end
from #t1
union all
select id, value, seq = 4
from #t2
) d
order by seq, convert(int, value)
You can check this below logic of ordering the output using CASE statement in the ORDER clause-
SELECT *
FROM
(
select 'T1' T_Name,* from #t1
union
select 'T2',* from #t2
)A
ORDER BY
CASE
WHEN t_name = 'T1' AND id = (SELECT MIN(ID) FROM #t1) THEN 1
WHEN t_name = 'T2' AND id = (SELECT MAX(ID) FROM #t2) THEN 2
WHEN t_name = 'T1' THEN 3
ELSE 4
END,
Id -- Or you can order by Value. Just keep in mind that Value is VARCHAR as per your setup. So, Ordering will be also impact accordingly.

Why does UNION returns only one null?

I understand null represents missing/unknown value, so a null is not equal to another null because two unknown things cannot be compared. For example
if null = null
select 'nulls are equal'
else
select 'nulls are not equal'
results in 'nulls are not equal' I used an = instead of is null or is not null here to emphasize the fact that two nulls cannot be compared.
Coming to UNION, UNION is supposed to eliminate duplicate values. I was expecting the below code to return two rows each with null since two null values are not equal, but I get only one null in the result set.
(select null as Col1)
union
(select null as Col1)
Why does SQL's interpretation of 'null as an unknown value' change in above two statements?
NULL is not comparable, but SQL generally does have the concept of "IS DISTINCT FROM"
SQL Server has a Connect item for it
1 IS DISTINCT FROM NULL = true
1 = null is false
For completeness, NULL IS DISTINCT FROM NULL = false
I would guess that DISTINCT and UNION use IS DISTINCT FROM (as Pரதீப் mentioned above)
Now, SQL Server does have IS DISTINCT FROM in INTERSECT and EXCEPT
DECLARE #t1 TABLE (t1col INT);
INSERT #t1 VALUES (1), (NULL), (2), (3), (3), (5), (5);
DECLARE #t2 TABLE (t2col INT);
INSERT #t2 VALUES (1), (NULL), (3), (4);
SELECT DISTINCT 't1 EXISTS t2', *
FROM #t1 t1 WHERE EXISTS (SELECT * FROM #t2 t2 WHERE t1.t1col = t2.t2col);
t1 EXISTS t2 1
t1 EXISTS t2 3
t1 EXISTS t2 3
SELECT DISTINCT 't1 INTERSECT t2', *
FROM #t1 INTERSECT SELECT 't1 INTERSECT t2', * FROM #t2;
t1 INTERSECT t2 NULL
t1 INTERSECT t2 1
t1 INTERSECT t2 3
INTERSECT and EXCEPT also remove duplicates because they do a semi-join
EXISTS is an anti-join BTW
For completeness
SELECT 't1 EXISTS t2', *
FROM #t1 t1 WHERE NOT EXISTS (SELECT * FROM #t2 t2 WHERE t1.t1col = t2.t2col);
t1 EXISTS t2 NULL
t1 EXISTS t2 2
t1 EXISTS t2 5
t1 EXISTS t2 5
SELECT 't1 EXCEPT t2', *
FROM #t1 EXCEPT SELECT 't1 EXCEPT t2', * FROM #t2;
t1 EXCEPT t2 2
t1 EXCEPT t2 5
Example taken from my answer Why does EXCEPT exist in T-SQL? with added NULLs
UNION is basically SELECT DISTINCT, so it would be eliminating duplicate NULL values, but it's not the same as Equal operation.
Using UNION ALL would give you all records including duplicating NULLs.
As for the first part of you question. NULL really equals NULL, but not with "=". This would give you result you expect:
if null IS null
select 'nulls are equal'
else
select 'nulls are not equal'
This is also helpful when dealing with nulls.
Try UNION ALL to retain everything in both sets without removing duplicates.

SQL Server: How to select top rows of a group based on value of the column of that group?

I have two tables like below.
table 1
id rem
1 2
2 1
table 2
id value
1 abc
1 xyz
1 mno
2 mnk
2 mjd
EDIT:
#output
id value
1 abc
1 xyz
2 mnk
What i want to do is select top 2 rows of table2 with id one as rem value is 2 for id 1 and top 1 row with id 2 as its rem value is 1 and so on. I am using MS sqlserver 2012 My whole scenario is more complex than this. Please help.
Thank you.
EDIT : I know that i should have given what i have done and how i am doing it but for this particular part i don't have idea for starting. I could do this by using while loop for each unique id but i want to do it in one go if possible.
First, SQL tables represent unordered sets. There is no specification of which values you get, unless you include an order by.
For this purpose, I would go with row_number():
select t2.*
from table1 t1 join
(select t2.*,
row_number() over (partition by id order by id) as seqnum
from table2 t2
) t2
on t1.id = t2.id and t2.seqnum <= t1.rem;
Note: The order by id in the windows clause should be based on which rows you want. If you don't care which rows, then order by id or order by (select null) is fine.
Try This:
DECLARE #tbl1 TABLE (id INT, rem INT)
INSERT INTO #tbl1 VALUES (1, 2), (2, 1)
DECLARE #tbl2 TABLE (id INT, value VARCHAR(10))
INSERT INTO #tbl2 VALUES (1, 'abc'), (1, 'xyz'),
(1, 'mno'), (2, 'mnk'), (2, 'mjd')
SELECT * FROM #tbl1 -- your table 1
SELECT * FROM #tbl2 -- your table 2
SELECT id,value,rem FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY T.ID ORDER BY T.ID) rowid,
T.id,T.value,F.rem FROM #tbl2 T LEFT JOIN #tbl1 F ON T.id = F.id ) A WHERE rowid = 1
-- your required output
Hope it helps.

Select two columns for two different tables in SQL Server 2000

I have a database with two tables (Table1 and Table2). Table1 has one column ColumnA and Table2 has one column ColumnB i want to select both the columns,
looking for something like:
ColumnA in Table1:
a
b
c
ColumnA in Table2:
d
e
f
Result set should be:
a d
b e
c f
Thanks in advance..
I am pretty sure sql server 2000 supports table vars so you can try this
DECLARE #TableA TABLE(
ID INT IDENTITY(1,1),
Val VARCHAR(50)
)
INSERT INTO #TableA (Val) SELECT ColumnA FROM Table1
DECLARE #TableB TABLE(
ID INT IDENTITY(1,1),
Val VARCHAR(50)
)
INSERT INTO #TableB (Val) SELECT ColumnB FROM Table2
SELECT a.Val,
b.Val
FROM #TableA a INNER JOIN
#TableB b ON a.ID = b.ID
Since you have no relation between the two tables, this operation is not really defined. What row in table1 goes with what row in table2?
You should set up a relation.
What is it you want to achieve anyway?
I don't know the big picture but from what you've said, here's an example. There has to be some way to define which record in table 1 should match up with a record in table 2. I'm assuming they match up on the ordering when ordered by the column in each table (e.g. record 1 from Table 1 ordered by column A, matches with record 1 from Table 2 ordered by column B). This example requires SQL 2005 or higher.
DECLARE #T1 TABLE (A varchar(10))
DECLARE #T2 TABLE (B varchar(10))
INSERT #T1 VALUES ('a')
INSERT #T1 VALUES ('b')
INSERT #T1 VALUES ('c')
INSERT #T2 VALUES ('d')
INSERT #T2 VALUES ('e')
INSERT #T2 VALUES ('f')
SELECT A, B
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY A ASC) AS RowNo, A
FROM #T1
) t1
JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY B ASC) AS RowNo, B
FROM #T2
) t2 ON t1.RowNo = t2.RowNo
How will the system know to associate the 'a' value from table1 with the 'd' value from table 2? If someone adds another row to table2 with value 'c' should your query now output
null- c
a - d
b - e
c - f
or
a - c
b - d
c - e
or
a - c
b - d
c - e
null- f
??? --- You have to specify in some way what rules to use to associate the rows from table1 with the rows from table2.
If you just want the rows associated based on alphabetical sorting,
then if the values are unique in each of the tables, (using standard SQL only), try this
Select Z1.ColumnA, z2.ColumnB
From (Select ColumnA,
(Select Count(*)
From Table1
Where ColumnA < t1.ColumnA) RowNo,
From Table1 T1) z1
Join (Select ColumnB,
(Select Count(*)
From Table2
Where ColumnB < t2.ColumnB) RowNo,
From Table2 T2) z2
On z1.RowNo = z2.RowNo
Order By z1.RowNo

Resources