I have a table contacts which has the PK fields name and idref
and another table called links that has the PK fields contactFK, type and groupid
For example
contacts
pk name idref
1 john 5634
2 jen 4525
3 james 5656
links
pk contactfk type groupid
1 1 primary 555
2 2 worker 555
3 3 primary 666
I want to show
name id groupid primaryid
john 5634 555 5634
jen 4525 555 5634
james 5656 666 5656
You can use a CTE to pull out the Primary Group IDs first and then join back to it for each user as such:
CREATE TABLE #Contacts(pk int, name varchar(50), idref int)
INSERT INTO #Contacts VALUES(1,'john', 5634),
(2,'jen', 4525),
(3,'james', 5656)
CREATE TABLE #links(pk int, contactfk int,type varchar(20),groupid int)
INSERT INTO #links VALUES(1,1,'primary', 555),
(2,2,'worker', 555),
(3,3,'primary',666)
;WITH CTE AS
(SELECT t1.idref, GROUPID
from #Contacts t1
INNER JOIN #links t2 on t2.contactfk = t1.pk
where t2.[type] = 'primary'
)
SELECT t1.name, t1.idref,t2.groupid, t3.idref PrimaryID
from #Contacts t1
INNER JOIN #links t2 on t1.pk = t2.contactfk
INNER JOIN CTE t3 on t3.groupid = t2.groupid
Select a.name, a.idref id, b.groupid primaryid from contacts a left outer join links b on a.pk = b.pk
Related
I have two tables in MSSQL with the same structure T1 & T2. Both tables can INNER JOIN on Id but T2 may not contain the AccountId associated with the Id as in T1.
.
T1 Id AccountId Name T2 Id AccountId Name
111 5555 John 111 5555 John
122 5555 David 133 5555 Sharon
133 5555 Sharon
Below is the code I tried but the result is not working?.
.
INSERT INTO T3
SELECT T1.Id,T1.AccountId,T1.Name
FROM T1
INNER JOIN T2 T2.Id = T1.id
LEFT OUTER JOIN T1.AccountId = T2.AccountId
WHERE AccountId = 5555
The expected result would be to insert values that are not in T1 into T3
You need where clause:
INSERT INTO T3(Id, AccountId, Name)
SELECT T1.Id, T1.AccountId, T1.Name
FROM T1 LEFT JOIN
T2
ON T2.Id = T1.id
WHERE T2.AccountId IS NOT NULL;
Notes:
Only one LEFT JOIN is necessary. I don't know what the INNER JOIN is for.
Every JOIN should be followed by an ON clause.
You should list the columns when doing an INSERT.
You need the WHERE to find non-matches.
This query could also be written using NOT EXISTS.
This should be what you're after:
CREATE TABLE #T1 (id int, AccountId int, [Name] varchar(6));
CREATE TABLE #T2 (id int, AccountId int, [Name] varchar(6));
CREATE TABLE #T3 (id int, AccountId int, [Name] varchar(6));
INSERT INTO #T1
VALUES (111,5555,'John '),
(122,5555,'David '),
(133,5555,'Sharon');
INSERT INTO #T2
VALUES (111,5555,'John '),
(133,5555,'Sharon');
INSERT INTO #T3 (id, AccountId, [Name])
SELECT T1.id,
T1.AccountId,
T1.[Name]
FROM #T1 T1
LEFT JOIN #T2 T2 ON T1.ID = T2.id
WHERE T2.id IS NULL;
SELECT *
FROM #t3;
DROP TABLE #T1;
DROP TABLE #T2;
DROP TABLE #T3;
I feel like there should be an easy way to do this.
Given two tables (ID is primary key, no duplicates):
TblQtyNew TblQtyUsed
ID | QtyNew ID | QtyUsed
1 15 1 7
2 18 3 21
How can I obtain the following result?
ID | QtyNew | QtyUsed
1 15 7
2 18 NULL
3 NULL 21
The only solution I have come up with involves a UNION on the ID column then two left joins:
(SELECT ID FROM TblQtyNew) UNION (SELECT ID FROM TblQtyUsed) as IDs
LEFT JOIN
(SELECT QtyNew FROM TblQtyNew) ON TblQtyNew.ID = IDs.ID
LEFT JOIN
(SELECT QtyUsed FROM TblQtyUsed) ON TblQtyUsed.ID = IDs.ID
Is there a more simple way to do this?
You can use full join and coalesce in id as below:
select coalesce(t1.id,t2.id) as Id, Qtynew, QtYused
from #table1 t1 full join #table2 t2
on t1.id = t2.id
Output:
+----+--------+---------+
| Id | Qtynew | QtYused |
+----+--------+---------+
| 1 | 15 | 7 |
| 2 | 18 | NULL |
| 3 | NULL | 21 |
+----+--------+---------+
You want a FULL OUTER JOIN:
SELECT COALESCE(T1.ID,T2.ID) as ID, T1.QtyNew, T2.QtyUsed
FROM TblQtyNew T1
FULL OUTER JOIN TblQtyUsed T2 on T1.ID = T2.ID
1.
SELECT ID,SUM(ISNULL(QtyNew)) AS QtyNew,SUM(ISNULL(QtyUsed)) AS QtyUsed
FROM (
SELECT ID,QtyNew,NULL AS QtyUsed FROM TblQtyNew
UNION ALL
SELECT ID,NULL QtyNew, QtyUsed FROM TblQtyUsed
) AS t
GROUP BY ID
2.
SELECT COALESCE(n.ID,U.ID) AS ID,n.QtyNew,u.QtyUsed
FROM TblQtyNew AS n FULL OUTER JOIN TblQtyUsed AS u ON n.ID=u.ID
Use FULL JOIN and Case:
DECLARE #T1 TABLE (id int , QtyNew int);
DECLARE #T2 TABLE( id int , QtyUsed int);
insert into #T1 values (1,15),(2,18);
insert into #T2 values (1,7),(3,21);
SELECT ID = case when T1.ID IS not Null then T1.ID else T2.ID end, T1.QtyNew, T2.QtyUsed
FROM #T1 T1
full JOIN #T2 T2 on T1.ID = T2.ID
Order by ID;
Demo
I intentionally trying alternate method.
declare #TblQtyNew table (ID int,QtyNew int)
insert into #TblQtyNew VALUES
(1,15)
,(2,18)
declare #TblQtyUsed table ( ID int, QtyUsed int)
insert into #TblQtyUsed VALUES
(1 ,7 )
,(3 ,21)
;with CTE as
(
select a.id,QtyNew,b.QtyUsed from #TblQtyNew a
inner join #TblQtyUsed b on a.id=b.ID
)
select * from CTE
union all
select a.id,QtyNew,null
from #TblQtyNew a
where not exists(select id from cte c where c.id=a.id)
union all
select a.id,null,QtyUsed
from #TblQtyUsed a
where not exists(select id from cte c where c.id=a.id)
select Id, QtyNew, QtyUsed
from TblQtyNew Full outer join TblQtyUsed
on TblQtyNew.ID=TBLQtyUsed.ID
I have two tables like below:
table1:
StoreId SKU
------------
1 abc
2 abc
3 abc
1 xyz
4 xyz
table2:
StoreId
--------
1
2
3
4
5
I want to select missing storeid from the table1 which are in table 2. But condition is that in above example for SKU abc storeid 4 and 5 are missing and for sku xyz 2,3,5 are missing. So I want below table as output
SKU,ID
------
abc 4
abc 5
xyz 2
xyz 3
xyz 5
I am able to pull only the overall missing store which is 5 using below query.
SELECT
SKU, t2.StoreId
FROM
#table1 t1
FULL OUTER JOIN
#table2 t2 ON t1.StoreId = t2.StoreId
WHERE
t1.StoreId IS NULL
Below is test create and insert query.
Declare #table1 As table
(
StoreId varchar(4),
SKU varchar(5)
)
Declare #table2 As table
(
StoreId int
)
BEGIN
Insert Into #table1(SKU,StoreId) values('abc',1)
Insert Into #table1(SKU,StoreId) values('abc',2)
Insert Into #table1(SKU,StoreId) values('abc',3)
Insert Into #table1(SKU,StoreId) values('xyz',1)
Insert Into #table1(SKU,StoreId) values('xyz',4)
Insert Into #table2(StoreId) values(1)
Insert Into #table2(StoreId) values(2)
Insert Into #table2(StoreId) values(3)
Insert Into #table2(StoreId) values(4)
Insert Into #table2(StoreId) values(5)
END
Thank you
You need to get a list of all skus and tables, and then show only rows which do not appear in table1:
select SKU, StoreID
from #table2 t2
cross join (select distinct sku from #table1) t1
where not exists (select 1 from #table1 table1
where table1.SKU = t1.SKU
and table1.StoreId = t2.StoreId)
Here is an alternative solution with the same result.
Syntax is very similar to the answer from #BeanFrog:
SELECT
t3.SKU, t2.StoreID
FROM
#table2 t2
CROSS JOIN
(SELECT distinct SKU
FROM #table1) t3
LEFT JOIN
#table1 t1
ON
t1.SKU = t3.SKU
and t1.StoreId = t2.StoreId
WHERE
t1.sku is null
I have 2 tables having IP_Address as common column. My requirement is to get the IP_Address and its associated details in table 1 that are for last 90 days and are not in table 2 and insert the delta in a new table on an nightly basis
DB used: oracle 11g
Table 3 should contain 1 record per IP_Address from Table 1 that are not in Table 2
Table 1
--------------------------------------------------
IP_Address Store_name source TRANS_INIT_TIME
--------------------------------------------------
192.168.0.1 abc e 16-06-29 05:49:16.775265000
192.168.0.1 abc e 16-07-01 07:44:29.019723000
192.168.0.2 ghi b 16-07-06 10:53:54.588610000
192.168.0.2 ghi b 16-07-12 04:04:20.293644000
192.168.0.3 hjg e 16-07-12 03:54:36.024915000
192.168.0.3 hjg e 16-07-15 03:46:27.712961000
192.168.0.4 uiu e 16-09-12 08:57:48.360136000
Table 2
--------------------------
IP.Address loc name
--------------------------
192.168.0.2 hjh uiui
Table 3
--------------------------------
IP_Address Store_name source
-------------------------------
I have prepared join to get the unique IP_Address from table1.
SELECT DISTINCT T1.IP_ADDRESS
FROM Table1 T1
LEFT JOIN TABLE2 T2
ON T1.IP_ADDRESS= T2.IP_ADDRESS
WHERE T1.TRANS_INIT_TIME BETWEEN SYSDATE-90 AND SYSDATE
AND T2.IP_ADDRESS IS NULL
AND T1.IP_ADDRESS IS NOT NULL;
I am struck here on how to get the first row data for these returns IPs and insert them in table 3 through procedure. can anyone help no this ?
Expected Result:
Table 3
--------------------------------
IP_Address Store_name source
-------------------------------
192.168.0.1 abc e
192.168.0.2 ghi b
192.168.0.3 hjg e
192.168.0.4 uiu e
In your case is enough test only the left join key column that is null (this mean that this key don't match with the key form the main table
and for insert you can use an insert select
INSERT INTO Table3 (IP_ADDRESS, Store_name, source)
SELECT DISTINCT T1.IP_ADDRESS, min(T1.Store_name), min(T1.Source)
FROM Table1 T1
LEFT JOIN TABLE2 T2
ON T1.IP_ADDRESS= T2.IP_ADDRESS
WHERE T1.TRANS_INIT_TIME BETWEEN SYSDATE-90 AND SYSDATE
and AND T2.IP_ADDRESS IS NULL
group by T1.IP_ADDRESS
You want the IP_ADDRESS to be unique in the result set but you haven't indicated which row you want for store_name and source. Just pick one randomly maybe? I'm not sure which one you want but here are three different ways to get that table3 you want.
Using an aggregate so you can group by IP_ADDRESS and correlated subquery:
SELECT T1.IP_ADDRESS, MAX(T1.STORE_NAME) AS STORE_NAME, MAX(T1.SOURCE) AS SOURCE
FROM Table1 T1
WHERE NOT EXISTS (SELECT NULL
FROM TABLE2 T2
WHERE T1.IP_ADDRESS = T2.IP_ADDRESS)
GROUP BY T1.IP_ADDRESS
ORDER BY T1.IP_ADDRESS;
Using an aggregate and a left outer join:
SELECT T1.IP_ADDRESS, MAX(T1.STORE_NAME) AS STORE_NAME, MAX(T1.SOURCE) AS SOURCE
FROM Table1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.IP_ADDRESS = T2.IP_ADDRESS
WHERE T2.IP_ADDRESS IS NULL
GROUP BY T1.IP_ADDRESS
ORDER BY T1.IP_ADDRESS;
Using an analytical function and correlated subquery:
SELECT SUB.IP_ADDRESS, SUB.STORE_NAME, SUB.SOURCE
FROM (
SELECT T1.IP_ADDRESS, T1.STORE_NAME, T1.SOURCE, ROW_NUMBER() OVER (PARTITION BY T1.IP_ADDRESS) AS ROWNUMBER
FROM Table1 T1
WHERE NOT EXISTS (SELECT NULL
FROM TABLE2 T2
WHERE T1.IP_ADDRESS = T2.IP_ADDRESS)
) AS SUB
WHERE SUB.ROWNUMBER = 1
ORDER BY SUB.IP_ADDRESS;
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