Using Partition By in an inner join to return a single value - sql

I have read a table and it returned a value. I now need to do an Inner Join with another table to get the next highest value available after this value in this Table.
I.e I have just returned the value 7 from a select and the Table I now need to join with contains the values;
1
5
7
11
20
I only want to return 11 in my join.
I have tried 'Row_Number () Over Partition By' but doesn't work for me because I am using an 'on (A.Number > B.Number) in the Join statement so the Row Number returned will not always be 1 for me.
Any advice?
I tried something like this;
SELECT a_number_field
FROM Table_A A
INNER JOIN (
SELECT ROW_NUMBER() OVER (
PARTITION BY another_number_field
ORDER BY another_number_field
) rn
FROM Table_B
) B
ON (b.another_number_field > a.A_number_field)
WHERE a.number_field = 7
and rn=1;
I am expecting only the value 11 to be returned to me.

Use the ROW_NUMBER with your join query as the following:
SELECT a_number_field, another_number_field
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY A.a_number_field ORDER BY another_number_field) rn FROM
tableA A JOIN tableB B
ON B.another_number_field > A.a_number_field
) T
WHERE rn = 1 AND a_number_field = 7
See a demo.

Related

Use Row_Number() in case statement in sql server

I Left Joined 2 table Table A and Table B and the output is below which is correct
select a.id,b.OS_ID from TableA left join TableB
on a.id=b.id
What I want to achieve is replacing NULL with 51 and 52.
If I run this
Declare #OSID int
set #OSID = (select max(os_ID) from OS_Master)
It will give me output as 50, Then I want to increment by 1 for the next entry and replace the NULL value
ID OS_ID
1 1
1 14
1 NULL
1 NULL
If I do this:
Declare #OSID int
set #OSID = (select max(os_ID) from OS_Master)
select ROW_NUMBER() over (order by os_ID) + #OSID from OS_Master
It works fine, ROW_NUMBER() starts from 51, But If I incorporate it with the join like
select a.ID,case when b.OS_ID is null then (select ROW_NUMBER() over (order by b.os_ID) + #OSID )
else b.OS_ID END from TABLEA a
left JOIN TABLEB b
on a.ID=b.ID
It shows 51 for both the NULL records, How to get 51,52 ans so on in my query
Is this what you want?
select a.id,
coalesce(b.OS_ID, om.max_os_id + row_number() over (partition by b.os_id)) as os_id
from TableA left join
TableB
on a.id = b.id cross join
(select max(os_ID) as max_os_id from OS_Master) om;
This increments the value based on the maximum value, using row_number().

How can I display two columns together in SQL?

I have 2 queries that return data in the form:
query 1:
column 1
a
b
c
query 2:
column 2
d
e
How can I combine the 2 queries to get output as:
column 1 column 2
a d
b e
c
The order of data in the columns does not matter.
Possibly anything with joins ?
Thanks
use row_number()
select t1.col1,t2.col2 from
(
select *,row_number() over(order by col1) rn from query1
) t1 full outer join
(
select *,row_number() over(order by col2) rn from query2
) t2 on t1.rn=t2.rn
For n,m rows use full outer join
A possible solution is selecting both columns with row_number() and join them by the row_number. One must be aware to select first from the table with the higher number of rows. Example:
select
col_1,
col_2
from (
select
a.col_1,
row_number() over () rn
from a
) s1
FULL OUTER JOIN (
select
b.col_2,
row_number() over () rn
from b
) s2 on s1.rn = s2.rn

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. in subquery sqlserver

I want to execute this query in my database.As you can see both tables A and B has one-many relations ,but i need the latest record in B.so i here is my query :
select *,(select top 1 ResultTest ,ResultState2 from B where GasReceptionId=A.Id order by Id desc)
from A where OrganizationGasId= 4212
But i get this error
Msg 116, Level 16, State 1, Line 2
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
You can rephrase this query as a basic join which uses an analytic function (e.g. row number) to identify the correct row's data from B to include with each record coming from the A table.
SELECT *
FROM
(
SELECT a.*, b.ResultTest, b.ResultState2,
ROW_NUMBER() OVER (PARTITION BY a.Id ORDER BY a.ID DESC) rn
FROM A a
LEFT JOIN B b
ON a.Id = b.GasReceptionId
WHERE
a.OrganizationGasId = 4212
) t
WHERE t.rn = 1;
A subquery in the SELECT clause must return exactly one column (and one or zero rows). So you can either have two subqueries:
select
a.*,
(select top 1 resulttest from b where gasreceptionid = a.id order by id desc) as test,
(select top 1 resultstate2 from b where gasreceptionid = a.id order by id desc) as state
from a
where a.organizationgasid = 4212;
Or, much better, move the subquery to the FROM clause. One way is OUTER APPLY:
select
a.*, r.resulttest, r.resultstate2
from a
outer apply
(
select top 1 resulttest, resultstate2
from b
where gasreceptionid = a.id
order by id desc
) r
where a.organizationgasid = 4212;

get latest records in group of records

i have the next table:
and i want to select only for every group of id the latest record by date
means, that the result will show: row 1 and row 3
how can i do it?
Your title says "latest" but you specified row 1 & 3.
Switch the MAX to a MIN depending on what you want.
;WITH cte
AS
(SELECT id,MAX([date]) AS [Date] FROM MyTable GROUP BY ID)
SELECT
A.*
FROM
MyTable A
INNER JOIN cte B
ON A.ID = B.ID
AND A.[Date] = B.[Date]
;

SQL Server ROW_NUMBER Left Join + when you don't know column names

I'm writing a page that will create a query (for non-db users) and it create the query and run it returning the results for them.
I am using row_number to handle custom pagination.
How do I do a left join and a row_number in a subquery when I don't know the specific columns I need to return. I tried to use * but I get an error that
The column '' was specified multiple times
Here is the query I tried:
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY Test) AS ROW_NUMBER, *
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50
Your query is going to fail in SQL Server regardless of the row_number() call. The * returns all columns, including a.id and b.id. These both have the same name. This is fine for a query, but for a subquery, all columns need distinct names.
You can use row_number() for an arbitrary ordering by using a "subquery with constant" in the order by clause:
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY (select NULL)) AS ROW_NUMBER, *
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50 ;
This removes the dependency on the underlying column name (assuming none are named ROW_NUMBER).
Try this sql. It should work.
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY a.Test) AS ROW_NUMBER, a.*,b.*
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50