How do i count occurences that were joined SQL - sql

I am joining two tables:
DECLARE #Temp TABLE (
id INT)
INSERT INTO #Temp
VALUES (5)
,(2)
,(3)
DECLARE #Temp2 TABLE (
member_id INT)
INSERT INTO #Temp2
VALUES (5)
,(1)
,(3)
How do i count the number of rows that can be LEFT joined and the ones that can't.
In this example: 5 & 3 from #Temp can be joined to #Temp2 and only 2 from #Temp can't be joined.
I would like my output to show the following:
+--------+------------+
| Joined | Not_Joined |
+--------+------------+
| 2 | 1 |
+--------+------------+

You can do this in a single query using COUNT and SUM. This should produce the results you are looking for.
DECLARE #Temp TABLE (
id INT)
INSERT INTO #Temp
VALUES (5)
,(2)
,(3)
DECLARE #Temp2 TABLE (
member_id INT)
INSERT INTO #Temp2
VALUES (5)
,(1)
,(3)
select Joined = count(t2.Member_id)
, NotJoined = sum(case when t2.Member_id is null then 1 end)
from #Temp t
left join #Temp2 t2 on t2.member_id = t.id

The count from #Temp that EXISTS in #Temp2:
SELECT COUNT(*) FROM #TEMP WHERE ID IN(SELECT MEMBER_ID FROM #TEMP2)
The count from #Temp2 not in #Temp:
SELECT COUNT(*) FROM #TEMP2 WHERE MEMBER_ID NOT IN(ID FROM #TEMP)
Now to create a single result set, there are many ways but here is a simple one:
SELECT
(SELECT COUNT(*) FROM #TEMP2 WHERE MEMBER_ID IN(ID FROM #TEMP)) AS [Joined],
(SELECT COUNT(*) FROM #TEMP WHERE ID NOT IN(SELECT MEMBER_ID FROM #TEMP2)) AS [NotJoined]
#Sean Lange's answer is more specific to the JOIN question, my answer simply counts what exists in the lists.

Select count(*) as 'NOT Joined ',
(Select t1.count(*) from table1
t1)-count(*) as 'Joined'
from table1 where id NOT IN (Select member_id from table2);
Its basically how a left join works that is Common values of both the
tables plus the value of table 1 which doesnt exists in table 2.

Related

Insert into each column of a table values based on conditions

I have a table of products like this:
I want to delete duplicate rows in this table and use the Ids in other tables, so I used a temporary table to add just the Ids to delete and the Ids to keep:
-- create tmp table
create table #tmp (ProductId_ToKeep int, ProductId_ToDelete int);
-- collect the Products that have a lower id with the same name in the temp table
insert into #tmp (ProductId_ToKeep)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] > t1.[ProductId]
);
-- collect the Products that have a higher id with the same name in the temp table
insert into #tmp (ProductId_ToDelete)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] < t1.[ProductId]
);
select * from #tmp
After getting what I have in my temp table, I got this result:
I'm asking if any can one help me to put the Ids in each column as I want.
If I followed you correctly, you could use a window function to feed the transcodification table in a single query, like so:
insert into #tmp (ProductId_ToKeep, ProductId_ToDelete)
select *
from (
select
ProductId ProductId_ToDelete,
min(ProductId) over(partition by name) ProductId_ToKeep
from dbo.[Product]
) t
where ProductId_ToDelete != ProductId_ToKeep
The inner query pulls out the smallest ProductId for the given name; the outer query filters on record that should be deleted (ie whose ProductId is not the minimum ProductId for the same name).

SQL Inner join and Not in

I am trying to run a query and not sure why the returned record set is off by 60 rows.
Select t1.* into #temp1
from NameExt as t1
join #temp1 as t2
on t1.AN = t2.AN --164172
Select t1.* into #temp3
from NameExt as t1
where AN in (Select AN from #temp1) --164112
When I do an intersect or except on #temp1 and #temp2, I dont get any rows back.
Really need to understand why the two queries are returning not a similar record set.
Even this returns the same number of rows as the 2nd query
Select * into #temp3 from NameExt as t1 where exists
( Select 1 from #temp1 as t2 where t1.AN = t2.AN) --164112
Thanks much
You can easily see what values are causing problems by doing:
select t2.AN
from #temp1 t2
group by t2.AN
having count(*) > 1;
Duplicates in the second table are causing the problem. You know how to fix it . . . using in or exists.
Your query is incorrect. You cannot select from and create a temp table at the same time..
Select t1.* into #temp1
from NameExt as t1
join #temp1 as t2
on t1.AN = t2.AN --164172
As per a comment, you likely have multiple rows in #temp1 with the same value in AN...
CREATE TABLE x (
id INT
)
CREATE TABLE y (
id INT,
x_id INT
)
INSERT INTO x VALUES (1), (2), (3)
INSERT INTO y VALUES (1, 2), (2, 2), (3, 3)
SELECT *
FROM x INNER JOIN y ON x.id = y.x_id
-- a total of three rows
-- x.id | y.id | y.x_id
------------------------
-- 2 | 1 | 2
-- 2 | 2 | 2
-- 3 | 3 | 3
SELECT *
FROM x
WHERE x.id IN (SELECT y.x_id FROM y)
-- a total of two rows
-- x.id
--------
-- 2
-- 3
http://sqlfiddle.com/#!18/7e1d1/2

Find Set of record rowno from multiple column

I have two sql temp table #Temp1 and #Temp2, and I want to get rowid which contain set of temp table two
E.g. In table Temp2 have 4 record i want to search in temp table #Temp1 which contain userid departmentid set of record
CREATE TABLE #Temp1(rowid INT, userid INT, departmentid int)
CREATE TABLE #Temp2(userid INT, deparetmentid int)
INSERT INTO #Temp1 (rowid,userid,departmentid )
VALUES (1,1,1),(1,2,2),(1,3,3),(1,4,4),(1,2,1),
(2,2,1),(2,2,2),(2,3,3),(2,4,4),
(3,3,1),(3,2,2),(3,3,3),(3,4,4)
INSERT INTO #Temp2 (userid,departmentid )
VALUES (2,1),(2,2),(3,3),(4,4)
DROP TABLE #Temp1
DROP TABLE #Temp2
i want output rowid 2 because it contain set of (2,1),(2,2),(3,3),(4,4)
one thing in rowid also contain same set of record it its have one more row mean
when i search in temp1 table based on rowid 1 then i found 4 record and when i search rowid 2 then it contain 4 record so that it is same set of record which i found
Thanks
You could use:
SELECT rowid
FROM #Temp1 t1
WHERE NOT EXISTS(SELECT userid, departmentid
FROM #Temp1 tx
WHERE tx.rowid=t1.rowid
EXCEPT
SELECT userid, departmentid
FROM #Temp2)
GROUP BY rowid
HAVING COUNT(*) = (SELECT COUNT(*) FROM #Temp2);
Output:
2
Rextester Demo
Let's assume the rows in table1 are unique. Then you can do this using join and group by:
select t1.rowid
from #table1 t1 left join
#table2 t2
on t1.userid = t2.userid and t1.departmentid = t2.departmentid
group by t1.rowid
having count(*) = (select count(*) from #table2 t2) and
count(*) = count(t2.userid) ;
This assumes no duplicates in either table.
Note: This returns rows that are identical to or a superset of the values in the second table.

SQL Join on partial column data (SQL Server)

Both columns are tinyint if it matters.
Table1
Version
--------
111115
222226
333337
Table2
ID Year
--------
5 2015
6 2016
7 2017
I need to join on the ID from table 2 if it equals the last value in the version field from table 1.
Version 111115 would join to ID 5. I know how to select on things like this but is joining feasible? The result being:
111115 5 2015
TIA!
You can use the RIGHT() function to do this:
SELECT *
FROM Table1 A
INNER JOIN Table2 B on RIGHT(A.Version,1) = B.ID
I would probably avoid having to do this very much though. It is a faulty database design. Perhaps add a column ID to table 1, and use:
UPDATE Table1
SET ID = RIGHT(Version,1)
Since they are both integer, you can try the modulus operator. It takes the remainder after division. So 111115 % 10 is 5.
SELECT *
FROM Table1 t1
INNER JOIN Table2 t2 on t1.Version % 10 = t2.ID
Declare #tblTest as table
(
id INT,
yearName INT
)
Declare #tblVersion as table
(
VersionNo INT
)
INSERT INTO #tblTest values(5,2015)
INSERT INTO #tblTest values(6,2016)
INSERT INTO #tblTest values(7,2017)
INSERT INTO #tblVersion values(111115)
INSERT INTO #tblVersion values(111116)
INSERT INTO #tblVersion values(111117)
select
*,RIGHT(VersionNo,1)
from #tblVersion
SELECT
*
FROM #tblTest T1
LEFT JOIN (SELECT RIGHT(VersionNo,1) AS VersionId,VersionNo FROM #tblVersion) T2 ON T2.VersionId=T1.id

Join Tables with no Join Criteria

This seems so simple, but I just can't figure it out. I want to simply join 2 tables together. I don't care which values are paired with which. Using TSQL, here is an example:
declare #tbl1 table(id int)
declare #tbl2 table(id int)
insert #tbl1 values(1)
insert #tbl1 values(2)
insert #tbl2 values(3)
insert #tbl2 values(4)
insert #tbl2 values(5)
select * from #tbl1, #tbl2
This returns 6 rows, but what kind of query will generate this (just slap the tables side-by-side):
1 3
2 4
null 5
You can give each table row numbers and then join on the row numbers:
WITH
Table1WithRowNumber as (
select row_number() over (order by id) as RowNumber, id from Table1
),
Table2WithRowNumber as (
select row_number() over (order by id) as RowNumber, id from Table2
)
SELECT Table1WithRowNumber.Id, Table2WithRowNumber.Id as Id2
FROM Table1WithRowNumber
FULL OUTER JOIN Table2WithRowNumber ON Table1WithRowNumber.RowNumber = Table2WithRowNumber.RowNumber
Edit: Modiifed to use FULL OUTER JOIN, so you get all rows (with nulls).
Use Cross Join
Select * From tableA Cross Join TableB
But understand you will get a row in the output for every combination of rows in TableA with every Row in TableB...
So if Table A has 8 rows, and TableB has 4 rows, you will get 32 rows of data...
If you want any less than that, you have to specify some join criteria, that will filter out the extra rows from the output
Well, this will work:
Select A.ID, B.ID From
(SELECT ROW_NUMBER () OVER (ORDER BY ID) AS RowNumber, ID FROM Tbl2 ) A
full outer join
(SELECT ROW_NUMBER () OVER (ORDER BY ID) AS RowNumber, ID FROM Tbl1 ) B
on (A.RowNumber=B.RowNumber)
The SQL1 cross join applies here also.
Select *
From tableA, TableB