SQL Server Simple Problem - sql

EDIT: I have written it a bit wrong gill change my Q
I'm a newbie with SQL and I have a Q..
I made 2 Temp. Tables.
Each has 25 Rows.(DateValue)
I want to combine this 2 tables in a third table..
First Table is [From]
Second Table is [To]...
Both tables have different values
I want to get it like this:
From| To |
1111|2222
2222|3333
3333|4444
etc..
I use this simple Query
Create Table #T3
(
[From] Datetime
,[To] Datetime
)
INSERT Into #T3
SELECT Distinct #T1.[From], #T2.[To]
From #T1,#T2
Where #T1.[From] is not null
And #T2.[To] is not null
Select * from #T3
Drop Table #T3
Drop Table #T2
Drop Table #T1
But my results are like this
From| To |
1111|1111
1111|2222
1111|3333
2222|1111
2222|2222
2222|3333
It multiplies the first field with the second wich gives me alot more records back..
Any help ?
THANKS !

After the OP's edit
This may work as you want (which is not entirely clear):
INSERT INTO #T3
SELECT #T1.[From]
, MIN(#T2.[To])
FROM #T1
JOIN #T2
ON #T1.[From] < #T2.[To]
GROUP BY #T1.[From]
Using
FROM T1, T2
results in all combinations or rows of T1 and T2. It's called a cross product and (properly) used with CROSS JOIN, like this:
FROM T1 CROSS JOIN T2
When you want to join the two tables based on a condition (and not get the cross product), you use a JOIN or INNER JOIN (these two are same thing):
FROM T1 JOIN T2
ON T1.[From] = T2.[To]
will get you all rows combinations where T1.From matches T2.To (on equality). I suppose you wanted to match every row of T1 with the row of T2 where T2.To was just larger than T1.From so I used the "smaller than" < operator instead of the "equality" = operator.
The GROUP BY and MIN() were added to get only the one with smallest T2.To from those rows.

It would do. It will insert a copy of table 2 for each line of table 1, as you didnt say how for it to work out how to extract what you want.
Now, assuming from and to are the same.. you can do
INSERT Into #T3
SELECT Distinct #T1.[From], #T2.[To]
From #T1 left join #T2 on #T1.[From]=#T2.[To]
Where #T1.[From] is not null
if this isnt how you mean (although having same value in both columns would seem counter productive in that sense), what other fields have you got and how would you tie the lines together.

Related

Is there any alternative way of achieving below logic in sql?

I have two tables -> tb1 and tb2.
I am performing left join operation on these tables using ID column and also i have one more condition such as one column is not equal to other column .
Below is sample code
select * from tb1 LEFT JOIN tb2 ON tb1.id=tb2.id AND tb1.pid!=tb2.pid;
I am able to get results from above query.
But i need to know is there any alternate ways to get same result using sql.?
The actually SQL standard uses <> instead of !=.
select * from tb1 LEFT JOIN tb2 ON tb1.id=tb2.id AND tb1.pid<>tb2.pid;
It seems to you not equal not working because of your join and join condition.
if we create two tables and create like your query
create table t1(id int,pid int);
create table t2 (id int,pid int );
insert into t1 values(1,2),(2,3),(3,4);
insert into t2 values(1,2),(2,3),(3,4);
select t1.* from t1 left join
t2 on t1.id=t2.id and
t1.pid!=t2.pid
order by t1.id
id pid
1 2
2 3
3 4
It returns all the values of 1st table, because LEFT JOIN returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side, if there is no match.
But if you put inner join in the same it will not return any row. so i think problem is not in the "not equal operator"

Selecting rowset when value exists in one of 5 tables with different amounts of columns

Using SQL Server, I Need to return the entire row from whatever table contains 'value' in the Filename column (A column each of the tables contain), but the tables do not have the same number of columns, and each table has unique columns with their own specific data types (The only column Name/Type they have in common is the Filename column that I need to check for 'value').
Ideally, I would be able to do something along the lines of:
SELECT * FROM Table1, Table2, Table3, Table4, Table5
WHERE Filename = 'someValue'
Since all tables share the same column name for the Filename.
I have tried using Union but have issues since the number of columns and datatypes of the tables do not align.
I have also tried every combination of JOIN I could find.
I'm sure this could be accomplished with IF EXISTS, but that would be many, many lines of what seems like unnecessary code. Hoping there is a more elegant solution.
Thanks in advance!
You can try to join the tables together. First create temporary table where you store the input. And then join the tables with this temporary to get all records you want. When there is no record for that filename in the table, then you will get NULL values.
create table Table1 (id int,value int);
insert into Table1 values (1,10)
create table Table2 (id int,value int);
insert into Table2 values (1,20)
create table Table3 (id int,value int);
insert into Table3 values (2,30)
Here is the query itself
create table #tmp (id int)
insert into #tmp
values (1)
select t.id, t1.value, t2.value, t3.value from #tmp as t
left join Table1 as t1
on t.id = t1.id
left join Table2 as t2
on t.id = t2.id
left join Table3 as t3
on t.id = t3.id
And this is what you get
id value value value
1 10 20 NULL
this should work too:
EXEC sp_MSforeachtable
#command1='SELECT * FROM ? where filename = ''someValue''',
#whereand='AND o.id in (select object_id from sys.tables where name in (''Table1'',''Table2'',''Table3''))'

Multiple table join

I have a scenario whereby I have 3 tables (Table1, Table2, Table3)
Table1 contains data whereby each MEMBNO is unique
I would like to JOIN to Table2 and Table3 to display results but only have one row for each result
I tried
SELECT A.MEMBNO,A.FIELD1,B.FIELD1,B.FIELD2,C.FIELD1
FROM Table1 A
INNER join Table2 B ON A.MEMBNO = B.MEMBNO
INNER join Table3 C ON A.MEMBNO = C.MEMBNO
but I get multiple results. If the MEMBNO is in Table2 twice and Table3 four times, I get 8 rows returned.
Is my JOIN correct or is the only way to control this through the WHERE statement after the JOIN to control what is returned from Table2 and Table3 (ie: does SQL "dumb" join all the data and expect the WHERE statement to be the filer?)
Many thanks
What you are fighting with is the different relationships between the data. Table1 is the primary key table which has your one row per MEMBNO. Table2\3 have more than one row for each MEMBNO. What you therefore need to think about is what data you actually want to see before you attempt the joins. The difference in cardinality is causing your row duplication when the joins are happening. If you want the data in Table2\3 to be squished into a single row, have a think how that might look. i.e. do you want to sum the numbers from the different rows into a total? do you want to take the maximum date? etc
Best thing to do is give some data examples from each table and give an example result. More than happy to have a go if you add that info.
As I am concern about only MEMBNO. What if I use distinct of MEMBNO from both tables Table2 and Table3.
Check the below example:
create table #t1
(
F1 int,
F2 int
)
Insert into #t1 values(1, 111)
Create table #t2
(
F1 int,
F2 int
)
Insert into #t2 values(1, 111)
Insert into #t2 values(1, 222)
Create table #t3
(
F1 int,
F2 int
)
Insert into #t3 values(1, 333)
Insert into #t3 values(1, 444)
SELECT a.*
FroM #t1 a left join (Select distinct f1 from #t2) b on a.F1 = b.f1
left join (Select distinct f1 from #t3) c on a.F1 = c.f1
Where #t1, #t2, #t3 are table1, table2, table3 respecively
AND F1 is your MEMBNO in all the tables.
You get multiple results because of using inner join.
You should use left or right join.

Compare two tables and insert the matching content to another table

I have been working on this problem for 3 months now and gave up once or twice. Yes, I am a novice. I created 3 tables with data. Table 1 has a letter and number. Table 2 has a name, letter and number. Table 3 has the end result. I want to compare the T1 and T2. If the name and number in T1 matches a name and number in table 2. I want the result to in T3 to include name, letter and number. This is what I have so far but it is not working.
SELECT * FROM T1 and SELECT * FROM T2
WHEN
TABLE T1(letter) && TABLE T2(letter)
AND
TABLE T1(number) && TABLE T2(letter)
INSERT INTO TABLE T3 (name,letter,number)
What you need is to do an inner join of the first and second tables based on the attributes name and letter.
SELECT T2.name, T2.letter, T2.number
FROM T1
INNER JOIN T2
ON T1.letter=T2.letter AND T1.number=T2.number;
For more details, you can refer http://www.w3schools.com/sql/sql_join.asp
To expand upon Dinesh's answer,
You'll need an inner join for this. Inner joins gives you rows that match the columns in both tables you've specified.
You can then combine it into an insert statement to put it into your T3 table. So this is one complete SQL statement:
INSERT INTO T3
SELECT T2.name, T2.letter, T2.number
FROM T2
INNER JOIN T1
ON T2.letter = T1.letter
AND T2.number = T1.number;
As a side note, there's also left joins and right joins (and heaps more). Think of Left, Inner, Right joins as two circles in a venn diagram.

SQLServer join two tables

I've gotta question for you, I'm getting hard times trying to combine two tables, I can't manage to find the correct query.
I have two tables:
T1: 1column, Has X records
T2: 1column, Has Y records
Note: Y could never be greater than X but it often lesser than this one
I want to join those tables in order to have a table with two columns
t3: ColumnFromT1, columnFromT2.
When Y is lesser than X, the T2 field values gets repeated and are spread over all my other values, but I want to get NULL when ALL the columns from T2 are used.
How could I achieve that?
Thanks
You could give each table a row number in a subquery. Then you can left join on that row number. To recycle rows from the second table, take the modulus % of the first table's row number.
Example:
select Sub1.col1
, Sub2.col1
from (
select row_number() over (order by col1) as rn
, *
from #T1
) Sub1
left join
(
select row_number() over (order by col1) as rn
, *
from #T2
) Sub2
on (Sub1.rn - 1) % (select count(*) from #T2) + 1 = Sub2.rn
Test data:
declare #t1 table (col1 int)
declare #t2 table (col1 datetime)
insert #t1 values (1), (2), (3), (4), (5)
insert #t2 values ('2010-01-01'), ('2012-02-02')
This prints:
1 2010-01-01
2 2012-02-02
3 2010-01-01
4 2012-02-02
5 2010-01-01
You are looking for a LEFT JOIN (http://www.w3schools.com/sql/sql_join_left.asp) eg . T1 LEFT JOIN T2
say they both have column CustomerID in common
SELECT *
FROM T1
LEFT JOIN
T2 on t1.CustomerId = T2.CustomerId
This will return all records in T1 and those that match in T2 with nulls for the T2 values where they do not match.
Make sure you are joining the tables on a common column (or common column set if more than one column are necessary to perform the join). If not, you are doing a cartesian join ( http://ezinearticles.com/?What-is-a-Cartesian-Join?&id=3560672 )