possibly left join with column value manipulation and condition check - sql

SELECT *
FROM table1 t1
LEFT JOIN table2 t2 ON t1.field_id = t2.field_id
WHERE t2.field_id IS NOT NULL
I'm trying to get the field_value from table 1 that does not exist in table 2
And add the row in table 2 and set is_selected = 0
I tried with join on t1.field_id = t2.field_id and t1.value_id != t2.field_value_lookup
Table 1
value_id field_id title
25 14 readonly1
26 14 readonly2
27 14 readonly3
1 13 optionA
2 13 optionB
Table 2
user_id field_id type_id field_value_lookup is_selected
260073 14 11 26 0
260073 14 11 27 1
Expected result in Table 2
user_id field_id type_id field_value_lookup is_selected
260073 14 11 26 0
260073 14 11 27 1
260073 14 11 25 0

Presuming Microsoft SQL Server
untested
select t2.user_id, t2.field_id, t2.type_id, t1.value_id field_value_lookup, 0 is_selected
from ( -- get the distinct existing information from table2 without field_value_lookup
select distinct user_id, field_id, type_id
from table2
) t2
inner join table1 t1 on t1.field_id = t2.field_id -- add all the values from table1
where not exists (select 1 -- exclude the rows that already exist
from table2
where user_id = t2.user_id
and field_id = t2.field_id
and type_id = t2.type_id
and field_value_lookup = t1.value_id
)

Related

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

sql outer join count above rows

table 1
_id sub_id
1 32
2 34
3 42
4 44
5 47
6 50
.
table 2
_id sub_id
1 34
2 42
i want result
_id sub_id count
1 32 2
2 34 2
3 42 1
4 44 0
5 47 0
6 50 0
table 2 sub id 34 contains table 1, above 32 -> count+1
table 2 sub id 42 contains table 1, above 32, 34, 42 -> count + 1
result
32, 34 = 2
42 = 1
44, 47, 50 = 0
i try outer join, left join etc....
not correct result.
how about this correct result?
plz. help me T.T....
Try this query
SELECT _id
,sub_id
,(
SELECT count(*)
FROM table2 t2
WHERE t2.sub_id >= t1.sub_id
) count
FROM table1 t1
This is what you want :
SELECT
t1._id
,t1.sub_id
,count(t2._id) as count
FROM
table1 t1
left join table2 t2
on t2.sub_id >= t1.sub_id
GROUP BY
t1._id
,t1.sub_id
Here is the SQLfiddle demo
select distinct a.id, a.sub_id,
case when c.sub_id is not null then (select count(*) from table2 b
where a.sub_id<=b.sub_id)
else 0 end as counter
from table1 a left join table2 c on c.sub_id>=a.sub_id
SQL Fiddle

sql join with not in column include in result

I have two table like
id Name allocation
2 Ash 15
3 Alam 18
4 Rifat 20
and
Date Id Present
24 2 10
24 3 15
25 2 10
25 3 12
25 4 12
Now i want to get the following result
Date Id Alloc Present
24 2 15 10
24 3 18 15
24 4 20 NULL
25 2 15 10
25 3 18 12
25 4 20 12
I've tried JOIN query but it does not give desired result
How to get the above result?
SELECT
t1.id
, dd.date
, t1.allocation
, t2.present
FROM
table1 AS t1 --- all items
CROSS JOIN
( SELECT DISTINCT date
FROM table2
) AS dd --- all dates
LEFT JOIN
table2 AS t2 --- present allocations
ON t2.id = t1.id
AND t2.date = dd.date ;
Tested at SQL-Fiddle: test (thank you #JW.)
There is also an interesting other way:
SELECT
t2.date,
t1.id,
t1.allocation,
MAX(CASE WHEN t1.id = t2.id THEN t2.Present ELSE NULL END)
FROM
table1 t1, table2 t2
GROUP BY
t1.id, t2.date, t1.allocation
ORDER BY
t2.date, t1.id
Stolen from: SQL query inner join with 0 values
http://www.sqlfiddle.com/#!3/d2ded/44

Joining multiple tables into one under one Id

I have dozen of tables with following format:
Table 1
[idA] [numA]
NULL 8
1 10
2 15
3 16
Table 2
[idB] [numB]
2 14
3 30
4 32
Table 3
[idC] [numC]
NULL 56
1 24
4 37
5 36
...
Now, I'm not sure how to formulate T-Sql query in order to produce following result:
[id] [numA] [numB] [numC] ...
NULL 8 0 56
1 10 0 24
2 15 14 0
3 16 30 0
4 0 32 37
5 0 0 36
Are there any suggestions on how to solve this?
I offer a solution with the full outer join, because that seems like the natural approach:
SELECT coalesce(a.id, b.id, c.id, . . .) as id,
a.NumA, b.NumB, c.NumC, . . .
FROM TableA a full outer join
TableB b
on a.id = b.id full outer join
TableC c
on coalesce(a.id, b.id) = c.id
However, the query needs to be written carefully, to keep the coalesces in line. The one advantage of this approach is that it should use indexes on the id columns for the query.
please try this
select id, max(numa),max(numb),max(numc) from
(
select id,numa,0 as numb,0 as numc from tb1
union all
select id,0 as numa,numb as numb,0 as numc from tb2
union all
select id,0 as numa,0 as numb,numc as numc from tb3
)X
group by id
order by id
Thanks
Rajath
SELECT Maintable.id,
Table1.numA,
Table2.numB,
Table3.numC
FROM (SELECT ida AS id
FROM Table1
UNION
SELECT idb AS id
FROM Table2
UNION
SELECT idc AS id
FROM Table3) MainTable
LEFT JOIN Table1
ON Maintable.id = Table1.Ida
LEFT JOIN Table2
ON Maintable.id = Table2.idB
LEFT JOIN Table3
ON Maintable.id = Table3.idC

Query results with no reverse

Ive got table:
UserA,
UserB,
numberOfConnections
I would like to write query which returns me only rows that has no reverse I mean or example :
for data :
1 2 10
1 3 10
1 5 10
1 6 10
2 6 10
2 5 10
5 1 10
5 2 10
3 1 10
it should return
1 2 10
1 3 10
1 5 10
1 6 10
2 6 10
2 5 10
rows:
5 1 10
5 2 10
3 1 10
arent valid because there are already corresponding
1 5 10
2 5 10
3 1 10
thanks for help
bye
This will do what you want
SELECT mt1.UserA, mt1.UserB, mt1.numberOfConnections
FROM MyTable mt1
LEFT OUTER JOIN MyTable mt2 ON mt1.UserA = mt2.UserB
AND mt1.UserB = mt2.UserA
WHERE mt2.UserA IS NULL
OR mt1.UserA < mt2.UserA
Why not add UserA < UserB in where clause. ?
Use Updated
A- Result No Reverse
Select UserA, UserB, numberOfConnections
From TName
Where ID Not IN(
SELECT t1.ID
FROM TName As t1 INNER JOIN TName As t2 ON (t1.UserA = t2.UserB) AND (t1.UserB = t2.UserA))
B- Result Reverse Only Repeted
Select UserA, UserB, numberOfConnections
From TName
Where ID IN(
SELECT t1.ID
FROM TName As t1 INNER JOIN TName As t2 ON (t1.UserA = t2.UserB) AND (t1.UserB = t2.UserA))
C- Result Reverse Only Not Repeted
Select UserA, UserB, numberOfConnections
From TName
Where ID IN(
SELECT t1.ID
FROM TName As t1 INNER JOIN TName As t2 ON (t1.UserA = t2.UserB) AND (t1.UserB = t2.UserA) and (t1.UserA<t1.UserB))
D- Result No Reverse and Not Repeted Reverse
A
Union
C
with t1 as (
select col1 ,col2,
row_number()
over(partition by case when col1>col2 then col1+col2 else col2+col1 end
order by case when col1>col2 then col1+col2 else col2+col1 end) as rownum
from table_1 )
select * from t1 where rownum =1
if your data type of col1 and col2 are not varchar, just cast them
you can replace the row_number by group by