I have two column given below
col1 col2
1 a
2 b
3 c
4 d
and my expected output is
col1 col2
1 d
2 c
3 b
4 a
One approach is to use subquery and self join with condition t1.col1+t2.col1=max(col1)+min(col1) which will enforce to have last value of t2 to be in same row with the first value of t1. But this approach will only work if you have sequential numbers without any gap in sequence.
If the number is always in proper sequence this can be faster in performance.
And another approach is with row_number(). You can have your data both in ascending and descending order then join them on their rownumber column and select col1 from ascending order and col2 from descending order.
This will be better approach if your dbms supports this, since any gap in the sequence is accepted here.
Schema:
create table test (col1 int, col2 varchar(10));
insert into test values(1 , 'a');
insert into test values(2 , 'b');
insert into test values(3 , 'c');
insert into test values(4 , 'd');
Query#1 with subquery and self join:
select t1.col1, t2.col2
from test t1 join
test t2
on t1.col1 + t2.col1 =(select max(col1)+min(col1) from test)
order by t1.col1
Output:
col1
col2
1
d
2
c
3
b
4
a
Query#2 with row_number()over():
select t1.col1,t2.col2 from
(select col1,col2,row_number()over(order by col1)rn from test)t1
inner join (select col1,col2,row_number()over(order by col1 desc)rn from test)t2
on t1.rn=t2.rn
output:
col1
col2
1
d
2
c
3
b
4
a
db<>fiddle here
For your given data, you can use a self-join:
select t.col1, t2.col2
from t join
t t2
on t2.id = 5 - t.id ;
This does not generalize particularly well.
Related
I have a table which requires me to ensure that a combination of attributes should have a unique record against it.
col1 col2 col3
a b x
a b y
a c x
a d z
e b w
How do I ensure that a col1+col2 combination only has unique col3 values. Here ab has both x and y as col3 values. I have to send such rows to a reject file and I am looking for the right filter query.
We can use an aggregation approach. To identify rows which are failing the unique requirement use:
WITH cte AS (
SELECT col1, col2
FROM yourTable
GROUP BY col1, col2
HAVING MIN(col3) <> MAX(col3)
)
SELECT t1.*
FROM yourTable t1
INNER JOIN cte t2
ON t2.col1 = t1.col1 AND
t2.col2 = t1.col2;
Need to insert Table1 Col1 value into Table2 Col1:
Input:
Table1
Col1
1,2,3,4
Output:
Table2
Col1
1
2
3
4
Use regexp_split_to_table():
select val
from table1 t1 cross join lateral
regexp_split_to_table(t1.col1, ',') val;
I have two tables. I am making a query on one table, and would like to join the result with a second table to get the final result.
My tables are:
create table table1 (col1 int, col2 int)
create table table2 (col3 int, col4 int)
insert into table1 values
(1, NULL), (2,10), (3, 20)
insert into table2 values
(1,100),(2,200),(3,300)
The query
SELECT col1 FROM table1 WHERE col2 IS NOT NULL
gives me
col1
2
3
How do I extend my query to receive the result as follows:
col1 col4
2 200
3 300
I put this example on SQL Fiddle http://sqlfiddle.com/#!3/9e89e/1 to quickly test queries.
SELECT t1.col1,t2.col4
FROM table1 t1
join table2 t2 on
t1.col1 = t2.col3
WHERE t1.col2 IS NOT NULL
You need to join the tables as per your expected output.
Fiddle
I have a table
col1
1
2
and other table
col1 col2 col3
1 1 data value one
1 2 data value one
2 3 data value two
and I want to join both tables to obtain the following result
col1 col2 col3
1 1 data value one
2 3 data value two
The second table have duplicates but I need to join only one (randomly). I've tried with Inner Join, Left Join, Right Join and always returns all rows. Actually I use SQL Server 2008.
select t1.col1, t2.col2, t2.col3 from table1 t1
cross apply
(select top 1 col2, col3 from table2 where col1 = t1.col1 order by newid()) t2
You can use the ROW_NUMBER Function along with ORDER BY NEWID() To get one random row for each value in col1:
WITH CTE AS
( SELECT Col1,
Col2,
Col3,
[RowNumber] = ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY NEWID())
FROM Table2
)
SELECT *
FROM Table1
INNER JOIN CTE
ON CTE.Col1 = table1.Col1
AND CTE.RowNumber = 1 -- ONLY GET ONE ROW FOR EACH VALUE
Use Distinct it will eliminate dups, but you sure both rows will contain same data?
I have a select statement returning 5 columns:
select col1,col2,col3,col4,col5 from table1;
col1 col2 col3 col4 col5
9 A B C D
8 E F G H
I have another select statement from table2 which returns col1 alone;
col1
8
9
Based on the two select queries, is there a way to write a single select query to return the result as:
col1 col2 col3 col4 col5
8 E F G H
9 A B C D
ie. basically sort the output of I query based on col1 from II query. (this is in Mysql)
PS:II table column1 is used to for sorting & that is coming from table 2. Table2's col1 is not static, its changing for every user action & based on a call i will get col1 of table 2 & need to sort with table1's output.
Use an ORDER BY:
SELECT col1,col2,col3,col4,col5
FROM table1
ORDER BY col1
By default, ORDER BY is ASC.
SELECT col1,col2,col3,col4,col5
FROM table1
ORDER BY col1 DESC
...will put 9 from col1 as the first record returned.
For this to work, you seriously need a sort column on table2. Just having the IDs in table2 is not enough. You can have the records 7,8,9, then delete 8 and add it back. But no, that doesn't order it as 7,9,8. Maybe temporarily if there is no primary key on the table, but when the table gets large, even that "implicit" order is lost.
So, assuming you have such a sort column
Table2
Sort, Col1
1, 9
2, 8
Your query becomes
SELECT a.*
FROM table1 a
INNER JOIN table2 b ON a.col1 = b.col1
ORDER BY b.sort ASC
If you still want to rely on MySQL undocumented features or the way it currently works, then you can try this.
# test tables
create table table1 (col1 int, col2 int, col3 int);
insert table1 select 8, 1,2; # in this order
insert table1 select 9, 3,4;
create table table2 (col1 int);
insert table2 select 9; # in this order
insert table2 select 8;
# select
SELECT a.*
FROM table1 a
INNER JOIN table2 b ON a.col1 = b.col1
----output----
col1 col2 col3
9 3 4
8 1 2
This works at least for small tables, only because size(table2) < size(table1) so it collects in that order, preserving the filesort on table2.col1.
Not sure what the relationship is between t1.col1 and t2.col2. Probably looking for something like this though:
SELECT t2.col1, t1.col2, t1.col3, t1.col4, t1.col5
FROM table2 t2
INNER JOIN table1 t1 ON t1.col1 = t2.col1
ORDER BY t2.col1 ASC