If value in both table then assign 1 - sql

Table1 CompanyID Location #-of-employees
5234 NY 10
5268 DC 2
5879 NY 8
6897 KS 100
8789 CA 1
9992 OH 201
9877 TX 15
Table2 CompanyID #-of-Shareholders
5234 5
5879 2
6897 4
8789 2
I have two table with the column CompanyID. In table2 you can find companies that have shareholders and in table1 you can find all the companies. So in table 1 I want to add a dummy variable that assign a 1 if the companyID is in table2(which means the company has shareholders) and a 0 if not.
Expected output:
Table1 CompanyID Location #-of-employees Dummy
5234 NY 10 1
5268 DC 2 0
5879 NY 8 1
6897 KS 100 1
8789 CA 1 1
9992 OH 201 0
9877 TX 15 0
I tried using this query but it doesn't give me the output I expect.
SELECT CASE WHEN companyID IN table2 THEN 1
ELSE 0
END AS dummy
FROM table1

You have to use the Subquery for this. the below code working fine.
SELECT CASE WHEN companyID in(select CompanyId from table2) THEN 1
ELSE 0
END AS dummy
FROM table1

You can use EXISTS
SELECT CASE
WHEN EXISTS(SELECT 1 FROM Table2 AS T2 WHERE T1.CompanyID = T2.CompanyID) THEN 1
ELSE 0
END AS Dummy
FROM Table1 AS T1;

If your DB's version is 2012+ then, use with left join as :
select t1.*, iif(#_of_Shareholders is null, 0, 1) as dummy
from table1 t1
left join table2 t2
on ( t1.CompanyID = t2.CompanyID );
else
select t1.*,
( case when #_of_Shareholders is null then 0 else 1 end )
as dummy
from table1 t1
left join table2 t2
on ( t1.CompanyID = t2.CompanyID );
or
select t1.*,
sign(coalesce(#_of_Shareholders,0))
as dummy
from table1 t1
left join table2 t2
on ( t1.CompanyID = t2.CompanyID );
Rextester Demo

Related

Conditional sum in SQL (SAS) (SUMIFS equivalent)

Let say I am working under SAS EG and I have 2 tables:
Table1:
Id Item
1 A
1 B
1 C
2 B
2 D
3 C
3 E
3 F
Table2:
Id Item Amount
1 A 99
2 C 100
1 B 100
2 A 90
1 A 93
3 B 92
1 E 93
2 B 99
1 A 93
Now I would like to take the sum conditional for my table1 from table2 (when the ID and the Item match).
Id Item Want
1 A 285
1 B 100
1 C 0
2 B 99
2 D 0
3 C 0
3 E 0
3 F 0
So what am I supposed to do in SQL?
Thanks in advance.
Use a correlated subquery to SUM:
select t1.Id, t1.Item,
(select sum(t2.amount) from table2 t2 where t2.id = t1.id and t2.item = t1.item)
from table1 t1
This looks like aggregation to me, with a left join:
select t1.id, t1.item,
coalesce(sum(t2.amount), 0) as want
from table1 t1 left join
table2 t2
on t1.id = t2.id and t2.item = t2.item
group by t1.id, t1.item;

Update row in TABLE1 using value from another row in TABLE1 to lookup value in TABLE2

I have a table as follows
TABLE1
Id UserId Type Value
1 AAA companyid 123
2 AAA branchid
3 BBB companyid 124
4 BBB branchid
5 CCC companyid 125
6 CCC branchid
and TABLE2
BranchId CompanyId Name
1 123 RedBranch
2 123 YellowBranch
3 123 GreenBranch
4 124 SouthBranch
5 125 NorthBranch
I need to update Type in TABLE1 WHERE Type = 'branchid' using the value in Type = 'companyid' for the same UserId. Once I have the correct 'companyid' I want to use the following SELECT to get the TOP BranchId from TABLE2
SELECT TOP 1 Id
FROM TABLE2
WHERE CompanyId = (correct companyid from TABLE1)
ORDER BY Id DESC
How can I achieve this in one Update statement?
Here's a stab at it:
update T1
set Value = (select max(BranchId) from Table2 where CompanyId = T1a.value)
from Table1 T1
inner join Table1 T1a on T1a.UserId = T1.UserId and T1a.Type = 'companyid'
where T1.Type = 'branchid'
I'm not sure that I fully understand the quesion, but maybe...
with maxBranch as
(
select
max(BranchId) as BranchId
,CompanyId
from TABLE2
group by CompanyId
)
update t1
set t1.Value = m.BranchID
from TABLE1 as t1
join TABLE1 as t11
on t1.UserId = t11.UserId
and t1.Type = 'branchid'
and t11.Type = 'companyid'
join maxBranch as m
on m.CompanyId = t11.Value

Waterfall join conditions

I have two tables similar to:
Table 1 --unique ID's
ID Date
1 3/8/2017
2 3/8/2017
3 3/8/2017
Table 2
ID Date SourceID
1 3/8/2017 1
1 3/8/2017 2
1 3/8/2017 3
2 3/8/2017 2
3 3/8/2017 1
3 3/8/2017 3
And I want to write a query that has a result like:
Result
ID SourceID
1 2
2 2
3 1
Where the source ID ordering should be 2, 1, 3
I have:
select Table1.ID
, COALESCE(Join1.SourceID, Join2.SourceID, Join3.SourceID) as SourceID
from Table1
left outer join Table2 Join1
on Table1.date = Join1.date
and Table1.ID = Join1.ID
and Join1.SourceID = 2
left outer join Table2 Join2
on Table1.date = Join2.date
and Table1.ID = Join2.ID
and Join2.SourceID = 1
and Join1.SourceID is null
left outer join Table2 Join3
on Table1.date = Join3.date
and Table1.ID = Join3.ID
and Join3.SourceID = 3
and Join1.SourceID is null
and Join2.SourceID is null
But this currently just keeps the records where sourceid = 2 and does not add in the other sourceid's.
Thanks in advance for any help. Let me know if you need any clarification. Using SQL-Server. I only need a few and fixed amount of sources so I am avoiding using a cursor.
This is a prioritization query. I would do it using outer apply:
select t1.*, t2.sourceId
from table1 t1 outer apply
(select top 1 t2.*
from table2 t2
where t2.id = t1.id and t2.date = t1.date
order by (case t2.sourceid when 2 then 1 when 1 then 2 when 3 then 3 end)
) t2;
Note: For readability, you can simplify the order by to:
order by charindex(cast(t2.sourceId as varchar(255)), '2,1,3')
If you are uncomfortable with outer apply, you can do the same thing with a single join:
select t1.*, t2.sourceId
from table1 t1 join
(select t2.*,
row_number() over (partition by id, date
order by (case t2.sourceid when 2 then 1 when 1 then 2 when 3 then 3 end)
) as seqnum
from table2 t2
) t2
on t2.id = t1.id and t2.date = t1.date and t2.seqnum = 1;

SQL LEFT JOIN first row only

Let's assume we have such data set:
Table: DataTable1
ID ExperienceId LanguageId ...
-------------------------------------------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 3
7 3 1
8 3 2
9 3 3
...
Table: DataTable2
ID SomeId OtherId LanguageId ...
-------------------------------------------
1 459 1 1
2 459 1 2
3 459 1 3
4 245 2 1
5 245 2 2
6 245 2 3
7 295 3 1
8 295 3 2
9 295 3 3
...
I want to join those tables and get only SomeId column ignoring the LanguageId column. To make it clearer:
SELECT
t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2
ON t2.OtherId = t1.ExperienceId
AND t2.LanguageId =
(SELECT TOP 1 t1.LanguageId
ORDER BY t1.LanguageId)
This query should return (if it wasn't wrong, clearly) rows:
SomeId ...
----------------
459 ...
245 ...
295 ...
...
Now it returns three times of identical data (with only LanguageId different).
I would try to filter it with WHERE t1.LanguageId = 1 if I was sure it always exists, but I'm not sure. Rows can be with LanguageId from 1 to 3, also they can be only with ID 2, etc. Rows surely will have at least one LanguageId.
Now my question is: how can I join tables with unique values with one column completely ignored?
Wrapping it in another query does the trick?
SELECT RequiredId, <all_the_other_fields> from (
SELECT t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2
ON t2.OtherId = t1.ExperienceId
AND t2.LanguageId =
(SELECT TOP 1 t1.LanguageId
ORDER BY t1.LanguageId)
) group by RequiredId, <all_the_other_fields>
or even not extracting the column in the first place?
SELECT distinct t2.SomeId AS RequiredId
-- ...other data mainly from t2 BUT not the Language id
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2
ON t2.OtherId = t1.ExperienceId
AND t2.LanguageId =
(SELECT TOP 1 t1.LanguageId
ORDER BY t1.LanguageId)
Try this:
;with cte as
(select *, row_number() over (partition by someid order by languageid) rn
from datatable2)
select *
from datatable1 dt
left join cte c on dt.experienceid = c.otherid and c.rn = 1
For such things when you need to select top in the subquery CROSS APPLY OR 'OUTER APPLY' is very handy
t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
OUTER APPLY ( SELECT TOP 1 t1.LanguageId
FROM DataTable2
WHERE DataTable2 .OtherId = t1.ExperienceId
AND t2.LanguageId = t1.LanguageId
ORDER BY t1.LanguageId
) AS t2
Try this:
SELECT DISTINCT t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2
ON t2.OtherId = t1.ExperienceId
WHERE t2.LanguageId = t1.LanguageId
Are you looking for this (Fiddle: http://sqlfiddle.com/#!3/811b8/12)?:
SELECT dt2.*
FROM DataTable1 dt1 INNER JOIN DataTable2 dt2
ON dt1.ExperienceID = dt2.OtherID AND
dt1.LanguageID = dt2.LanguageID
WHERE dt2.LanguageID = (SELECT MIN(LanguageID) FROM DataTable1);
produces:
ID SOMEID OTHERID LANGUAGEID
1 459 1 1
4 245 2 1
7 295 3 1

Design SQL Query for following case

Consider tables
Table1
id, name
1 xyz
2 abc
3 pqr
Table2
id title
1 Mg1
2 Mg2
3 SG1
Table3
Tb1_id tb2_id count
1 1 3
1 2 3
1 3 4
2 2 1
3 2 2
3 3 2
I want to do query to give result like
id title
1 MG1
2 MG2
3 Two or More Title
MG1 has higher preference if MG1 and count >= 1 then it is given as MG1 title , for others corresponding title is used and for count > 1 as two or more
I think this is what you are going for:
select t3.Tb1_id as id,
case
when mg1cnt.count >= 1 then 'MG1'
when cnt.count = 1 then upper(t2.title)
else 'Two or More Titles'
end as title
from (
select Tb1_id, count(*) as count
from Table3
group by Tb1_id
) cnt
inner join (
select Tb1_id, isnull(SUM(case when t2.title='mg1' then 1 end), 0) as count
from Table3 t3
inner join Table2 t2 on t3.tb2_id = t2.id
group by Tb1_id
) as mg1cnt on cnt.Tb1_id = mg1cnt.Tb1_id
inner join Table3 t3 on cnt.Tb1_id = t3.Tb1_id
inner join Table2 t2 on t3.tb2_id = t2.id
group by t3.Tb1_id,
case
when mg1cnt.count >= 1 then 'MG1'
when cnt.count = 1 then upper(t2.title)
else 'Two or More Titles'
end