SQL Creating a view with an additional sum column - sql-server

Hi I'm trying to create a view from two different tables that has an additional column that is a sum of Table1.Price1 - Table2.Price2. The view without the additional column is:
Create View testview AS (
SELECT t1.ID,t1.Price1,t2.Price2 FROM
Table1 t1
LEFT JOIN
Table2 t2
ON
t1.ID = t2.ID
);
Any help would be much appreciated, thank you.
Below is a representation of what the view would look like:
ID | Table1.Price1 | Table2.Price2 | Total |
---------------------------------------
1 | 15.00 | 5.00 | 10.00 |
2 | 10.00 | 2.50 | 7.50 |

Try this:
Create View testview AS
(SELECT t1.ID,t1.Price1,t2.Price2, (t1.Price1 - t2.Price2) as difference
FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.ID = t2.ID );

Just add your SUM column, like this:
Create View testview AS (
SELECT t1.ID,t1.Price1,t2.Price2, t1.Price1-t2.Price2 AS [SUM] FROM
Table1 t1
LEFT JOIN
Table2 t2
ON
t1.ID = t2.ID
);

You can just add two columns with the +,-,*,/ operators like in:
Create View testview AS (
SELECT t1.ID,t1.Price1,t2.Price2, t1.Price1+t2.Price2 as total FROM
Table1 t1
LEFT JOIN
Table2 t2 ON t1.ID = t2.ID
);
This will result in your desired table structure

Related

SQL Server query about joining 2 table with union

I have two tables T1 and T2, both of them contain a column ID and value.
I need to join T1 and T2 into T3 by means of ID.
T3 should contain columns ID, T1Value, and T2Value.
The main requirement is, ID of T1 and T2 is possible not mapped
T1:
ID VALUE
-----------
1 hi
2 hello
T2:
ID VALUE
----------
2 kitty
3 dog
Then, T3 should be
ID T1VALUE T2VALUE
----------------------
1 hi
2 hello kitty
3 dog
Is it possible to achieve this without using pivot table, or temp table (ideally should be a single executable query)?
Thanks.
You can use FULL OUTER JOIN
SELECT ID = COALESCE(T1.ID, T2.ID),
T1VALUE = T1.VALUE,
T2VALUE = T2.VALUE
FROM T1
FULL OUTER JOIN T2
ON T1.ID = T2.ID
There are lots of example on FULL OUTER JOIN . just search for it
Another way is to use UNION ALL
SELECT T1.ID, T1VALUE = T1.VALUE, T2VALUE = NULL
FROM T1
UNION ALL
SELECT T2.ID, T1VALUE = NULL, T2VALUE = T2.VALUE
FROM T2

Avoid Cross Joins in SQL Server

I have 2 tables T1 and T2.
T1:
ID | Name
----+-------
A | A1
A | C1
T2:
ID | Name
-----+------
A | A1
A | B1
I want to retrieve records that have same ID and Name with flag 1 and Same ID and Different Name with flag 0. However, while joining the table in SQL Server, I am getting the a cross join which is:
A | A1 | A1 | 1
A | A1 | B1 | 0
A | C1 | A1 | 0
A | C1 | B1 | 0
But I need the answer as:
A | A1 | A1 | 1
A | C1 | B1 | 0
The above result is giving me the same information about name mismatch but in limited no. of rows and no repetition.
Could somebody let me know how can do this in SQL Server?
Is this what you're after:
SELECT T1.ID, T1.Name Name1, T2.Name Name2, case T1.Name when T2.Name then 1 else 0 end Result
from T1
inner join T2 on T1.ID = T2.ID
where T1.Name = T2.Name
or (not exists (select 1 from T2 where T1.Name = Name and T1.ID = ID)
and not exists (select 1 from T1 where T2.Name = Name and T2.ID = ID))
Use a union to keep things simple:
select T1.ID, T1.Name Name1, T2.Name Name2, 1 flag
from T1
join T2 on T1.ID = T2.ID
and T1.Name = T2.Name
union all
select T1.ID, T1.Name, T2.Name, 0
from T1
join T2 on T1.ID = T2.ID
and T1.Name != T2.Name
Using a union is not the most efficient way, but it’s much easier to understand and unless you have millions of rows, it will still run very fast (and union all is quite a bit faster than union)
you can use ROW_NUMBER and FULL JOIN
DECLARE #T1 TABLE (ID VARCHAR(5), Name VARCHAR(5))
INSERT INTO #T1 VALUES ('A', 'A1')
INSERT INTO #T1 VALUES('A', 'C1')
DECLARE #T2 TABLE (ID VARCHAR(5), Name VARCHAR(5))
INSERT INTO #T2 VALUES ('A', 'A1')
INSERT INTO #T2 VALUES ('A', 'B1')
SELECT T1.ID, T1.Name, T2.Name, CASE WHEN T1.Name = T2.Name THEN 1 ELSE 0 END
FROM
( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM #T1 ) T1
FULL JOIN
( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM #T2 ) T2
ON T1.ID = T2.ID AND T1.RN = T2.RN
Result:
ID Name Name
----- ----- ----- -----------
A A1 A1 1
A C1 B1 0

Joining two SQL tables directly OR via junction table

I've been grappling with a problem for some time, checking thread after thread on S/O to no avail. I should mention I'm building a SQL query for use in Crystal Reports.
I am attempting to join two tables together that MAY be joined via a junction table - this can be done via UNIONs but the table then links to itself and it can become very messy accounting for all potential scenarios.
Let's say we have three tables: t1, t2 and t3.
I'm after a quick and reusable way to say "LEFT JOIN t1 & t2 directly OR LEFT JOIN via table3".
Here's a really basic knock-up of what I'm looking for:
SELECT t1.ID, t2.ID
FROM t AS t1
LEFT JOIN (
t AS t2 ON t1.ID = t2.parentID OR (
t AS t2 ON t1.ID = t3.ID1 AND t3.ID2 = t2.ID ))
Is this at all possible without ending up with two versions of t2?
I'm hoping there's a function out there I'm just unaware of.
EDIT: the direct t2 join is to a 'parentId' column on t2 and t1 & t2 are aliases of the same column.
Here's my desired output:
+-------+--------+--------+-------+-------------+
| t1.ID | t3.ID1 | t3.ID2 | t2.ID | t2.parentID |
+-------+--------+--------+-------+-------------+
| 001 | NULL | NULL | 004 | 001 |
| 002 | 002 | 003 | 003 | NULL |
| 003 | NULL | NULL | NULL | NULL |
+-------+--------+--------+-------+-------------+
This probably close to your request. But if t3.ID1 is on the same domain than t2.ID you can have problems
SELECT t1.ID, t2.ID
FROM t1
LEFT JOIN t3
ON t1.ID = t3.ID1
LEFT JOIN t2
ON t1.ID = t2.ID
OR t3.ID2 = t2.ID
So maybe you can include some validations
SELECT S.ID1, COALESCE(S.ID2, T2.ID)
FROM
( SELECT t1.ID as ID1, t2.ID as ID2
FROM t1
LEFT JOIN t2
ON t1.ID = t2.ID
-- This step look weird if t1.ID = t2.ID you just print same ID twice.
) as S
LEFT JOIN t3
ON S.ID1 = t3.ID1
AND S.ID2 IS NULL -- ONLY JOIN IF NOT MATCH ON FIRST QUERY
LEFT JOIN t2
ON t2.ID1 = t2.ID

Filtering the distinct rows from Table

I have a table with two columns schema as:
ID1,ID2
Values are as:
x y
y x
a b
b a
I just want resultset as a whole like:
x y
a b
I want to remove duplicate
Need the sql query for the same.
One of the ways to achieve this is to use LEFT JOIN like this.
SQL Fiddle
Query
SELECT T1.ID1,T1.ID2
FROM YourTable T1
LEFT JOIN YourTable T2
ON T1.ID1 = T2.ID2
AND T1.ID2 = T2.ID1
AND T2.ID1 < T2.ID2
WHERE T2.ID1 IS NULL
Output
| ID1 | ID2 |
|-----|-----|
| x | y |
| a | b |
I suggest you to use EXISTS like this:
SELECT *
FROM yourTable t
WHERE NOT EXISTS(SELECT 1 FROM yourTable ti
WHERE t.ID1 = ti.ID2 AND t.ID2 = ti.ID1
AND ti.ID1 > ti.ID2)

How to get column of table with a self-referencing foreign key?

I have a table structure shown below:
Id Name Sal ManagerId
1 a 5000 2
2 b 7000 3
3 c 6000 1
I need output like this
Id Name Sal Manager
1 a 5000 b
2 b 7000 c
3 c 6000 a
How can i do that?
You have to use a self-JOIN to link one table to itself:
SELECT t1.Id, t1.Name, t1.Sal, t2.ManagerName AS Manager
FROM TableName t1 INNER JOIN TableName t2
ON t1.ManagerID = t2.Id
If ManagerId is nullable you might want to use an OUTER JOIN:
SELECT t1.Id, t1.Name, t1.Sal, COALESCE(t2.ManagerName, '<no manager>') AS Manager
FROM TableName t1 LEFT OUTER JOIN TableName t2
ON t1.ManagerID = t2.Id

Resources