How to do distinct by first column - sql

Select DISTINCT wpg.ID as id1,wr.ID as id2
FROM Table1 wpg
inner join Table2 wp ON wp.WpgId = wpg.ID
inner join Table3 wr ON wr.WpId = wp.ID
I need wpg.Id distinct how do this?
I need from:
1 2
2 3
1 4
get:
1 2
2 3

The answer depends on what you want to do with the second column. I'm assuming you want the smallest value:
select
wpg.ID as id1,
min(wr.ID) as id2
from
Table1 wpg
inner join Table2 wp on wp.WpgId = wpg.ID
inner join Table3 wr on wr.WpId = wp.ID
group by
wpg.ID

select wpg.ID, min(wr.ID)
FROM Table1 wpg
inner join Table2 wp ON wp.WpgId = wpg.ID
inner join Table3 wr ON wr.WpId = wp.ID
group by wpg.ID

Related

Sql query to get join of two tables and both table has where query

Stuck at join, tried left, right, left outer , right outer joins
table 1
selectionID name type
1 abc 1
2 def 1
3 ghi 2
4 dhi 2
5 gki 2
6 ppp 2
Table 2
TID UserID selectionID isOK
1 10 3 0
2 19 3 0
3 10 8 0
6 10 5 1
Desired result is
join of
select from table 1 where type =2
select from table 2 where UserID = 10
selectionID name type TID userID
3 ghi 2 1 10
4 dhi 2 undefined undefined/null
5 gki 2 undefined undefined/null
6 ppp 2 6 10
so basically i want all data from table 1 that fits in where clause and their respective data in table 2 with another where clause
As long as i have done research i need to use inner query of second table...am I going right way?
Try the following query:
SELECT t1.selectionID, t1.name, t1.type, t2.tid, t2.userID
FROM table1 t1 LEFT JOIN table2 t2 ON t1.type = t2.TID AND t2.userID = 10
WHERE t1.type = 2;
Stuck at join, tried left, right, left outer , right outer joins ... well LEFT JOIN is same as LEFT OUTER JOIN. BTW, you are looking for a LEFT JOIN probably like
select t1.selectionID,
t1.name,
t1.type,
t2.TID,
t2.UserId
from table1 t1
left join table2 t2 on t1.selectionID = t2.selectionID
and t2.UserId = 10
where t1.type = 2;
You were probably failing because placing the conditions in the where clause. If a row doesn't join you will have nulls in its columns, so a where condition will discard those rows
select *
from table1 t1
left join
table2 t2
on t1.selectionID = t2.selectionID and
t2.userID = 10
where t1.type = 2
Another way, is to force nulled rows to be accepted, using coalesce
select *
from table1 t1
left join
table2 t2
on t1.selectionID = t2.selectionID and
where t1.type = 2 and
coalesce(t2.userID, 10) = 10
select * from table1 t1
left join table2 t2 ON t1.SelectionID = t2.SelectionID
where t1.type = 2 AND t2.UserID = 10

Different output when using count and group by

When trying to get a count of IDs I get a different answer when grouping by day vs when I am not.
select cv.CONV_DAY, count(distinct cv.CLICK_ID)
from
clickcache.click cc
right join(
select distinct cv.CLICK_ID, cv.CONV_DAY, cv.PIXEL_ID
from clickcache.CONVERSION cv
where cv.CLICK_ID IS NOT NULL) cv ON cv.CLICK_ID = cc.ID
where cc.ADV_ACCOUNT_ID = 25176
and cv.CONV_DAY between '2016-8-01' AND '2016-08-07'
and AMP_CLICK_STATUS_ID = 1
AND pixel_id IN
(SELECT DISTINCT conversion_pixel_id
FROM
ampx.campaign_event_funnel ef
JOIN ampx.campaign cp ON
cp.id = ef.campaign_id
AND cp.campaign_status_id = 1
WHERE
ef.account_id IN(25176)
AND include_optimization = 1 )
group by 1
order by 1 asc
This yields 170 which is the correct answer and the I want. This, on the other hand, displays 157.
select count(distinct cv.CLICK_ID)
from
clickcache.click cc
right join(
select distinct cv.CLICK_ID, cv.CONV_DAY, cv.PIXEL_ID
from clickcache.CONVERSION cv
where cv.CLICK_ID IS NOT NULL) cv ON cv.CLICK_ID = cc.ID
where cc.ADV_ACCOUNT_ID = 25176
and cv.CONV_DAY between '2016-8-01' AND '2016-08-07'
and AMP_CLICK_STATUS_ID = 1
AND pixel_id IN
(SELECT DISTINCT conversion_pixel_id
FROM
ampx.campaign_event_funnel ef
JOIN ampx.campaign cp ON
cp.id = ef.campaign_id
AND cp.campaign_status_id = 1
WHERE
ef.account_id IN(25176)
AND include_optimization = 1 )
My question is why do I get this discrepancy and how to fix it to get a proper count?
Thank you!
Your count dependents from right query, maybe you have duplicate row?
example
table1
id name value
1 2 3
table2
id name value
1 4 5
2 6 3
1 6 3
right join tables on value get result
select * from table1 a right join table2 b on a.value = b.value
1 2 3 2 6 3
1 2 3 1 6 3
select count(distinct a.value)
from (select a.id, a.name, a.value, b.id, b.name, b.value
from table1 a right join table2 b on a.value = b.value)
result is 1
select b.id, count(distinct a.value)
from (select a.id, a.name, a.value, b.id, b.name, b.value
from table1 a right join table2 b on a.value = b.value group)
group by b.id
result is two rows
2 1
1 1
My guess is that, you have a problem for this reason.

Sql oracle left join only match single rows

I need short sql to left join T2 on T1 only if single math
T1 T2 Desired
F1 F2 F1 F2 F1 F2
1 A A RR 1
2 B A 2 UU
3 C A TT 3
4 D B UU 4 YY
5 E C VV 5 ZZ
C XX
D YY
E ZZ
You could use a simple GROUP BY/COUNT to count the rows per hit and a CASE expression to only output the value if the row count is <=1;
SELECT T1.F1, CASE WHEN COUNT(*)>1 THEN NULL ELSE MAX(T2.F2) END F2
FROM T1
LEFT JOIN T2 ON T1.F2 = T2.F1
GROUP BY T1.F1
An SQLfiddle to test with.
USING group by to eliminate the records with duplicates and doing left join to get all values from T1
select T1.F1, ISNULL(T2.F2,'') from T1
LEFT JOIN
(
select F1 from T2
group by F1
having count(*) =1
) T
on T1.F1 = T.F1
LEFT JOIN T2
on T2.F1 = T.F1

Join tables with different data in rows

I have two tables like this
t1
id value1
BMC 16
EC 22
LLU 60
MC 274
UHC 54
UHS 28
t2
id value2
BMC 5
e900 4
EC 7
LLU 2
MC 1
How could I get this out put using sql server? I have used full outer join also. But its not gives me correct results
BMC 16 5
EC 22 7
LLU 60 2
MC 274 1
UHC 54
UHS 28
e900 4
Here is my outer join, Its for two select statements. Not for tables. But those select statements gives above results (t1, t2)
SELECT * FROM
(
SELECT b.EntityCode, COUNT('a') AS GroupCountUser1 FROM #TempUser a INNER JOIN OP_TB_TRN_Entity b
ON a.Entity=b.EntityID
GROUP BY b.EntityCode
) t1
FULL OUTER JOIN
(SELECT b.EntityCode, COUNT('a') AS GroupCountUser2 FROM #TempUser1 a INNER JOIN OP_TB_TRN_Entity b
ON a.Entity=b.EntityID
GROUP BY b.EntityCode) t2
ON t1.EntityCode = t2.EntityCode
Guessing you are forgetting to coalesce the IDs, try
Select coalesce( A.Id, B.Id) id,
A.Value1, B.Value2
From A Full Join B On A.Id = B.Id
Select concat( t1.value1, t2.value2) as totalvalue
From t1 join t2 where t1.Id = t2.Id
If i understand what you're asking, this should help.

SQL: 3 self-joins and then join them together

I have 2 tables to join in a specific way. I think my query is right, but not sure.
select t1.userID, t3.Answer Unit, t5.Answer Demo
FROM
table1 t1
inner join (select * from table2) t3 ON t1.userID = t3.userID
inner join (select * from table2) t5 ON t1.userID = t5.userID
where
NOT EXISTS (SELECT * FROM table1 t2 WHERE t2.userID = t1.userID AND t2.date > t1.date)
and NOT EXISTS (SELECT * FROM table2 t4 WHERE t4.userID = t3.userID and t4.counter > t3.counter)
and NOT EXISTS (SELECT * FROM table2 t6 WHERE t6.userID = t5.userID and t6.counter > t5.counter)
and t1.date_submitted >'1/1/2009'
and t3.question = Unit
and t5.question = Demo
order by
t1.userID
From table1 I want distinct userID where date > 1/1/2009
table1
userID Date
1 1/2/2009
1 1/2/2009
2 1/2/2009
3 1/2/2009
4 1/1/2008
So The result I want from table1 should be this:
userID
1
2
3
I then want to join this on userID with table2, which looks like this:
table2
userID question answer counter
1 Unit A 1
1 Demo x 1
1 Prod 100 1
2 Unit B 1
2 Demo Y 1
3 Prod 100 1
4 Unit A 1
1 Unit B 2
1 Demo x 2
1 Prod 100 2
2 Unit B 2
2 Demo Z 2
3 Prod 100 2
4 Unit A 2
I want to join table1 with table2 with this result:
userID Unit Demo
1 B X
2 B Z
In other words,
select distinct userID from table2 where question = Unit for the highest counter
and then
select distinct userID from table2 where question = Demo for the highest counter.
I think what I've done is 3 self-joins then joined those 3 together.
Do you think it's right?
SELECT du.userID, unit.answer, demo.answer
FROM (
SELECT DISTINCT userID
FROM table1
WHERE date > '1/1/2009'
) du
LEFT JOIN
table2 unit
ON (userID, question, counter) IN
(
SELECT du.userID, 'Unit', MAX(counter)
FROM table2 td
WHERE userID = du.userID
AND question = 'Unit'
)
LEFT JOIN
table2 demo
ON (userID, question, counter) IN
(
SELECT du.userID, 'Demo', MAX(counter)
FROM table2 td
WHERE userID = du.userID
AND question = 'Demo'
)
Having an index on table2 (userID, question, counter) will greatly improve this query.
Since you mentioned SQL Server 2005, the following will be easier and more efficient:
SELECT du.userID,
(
SELECT TOP 1 answer
FROM table2 ti
WHERE ti.user = du.userID
AND ti.question = 'Unit'
ORDER BY
counter DESC
) AS unit_answer,
(
SELECT TOP 1 answer
FROM table2 ti
WHERE ti.user = du.userID
AND ti.question = 'Demo'
ORDER BY
counter DESC
) AS demo_answer
FROM (
SELECT DISTINCT userID
WHERE date > '1/1/2009'
FROM table1
) du
To aggregate:
SELECT answer, COUNT(*)
FROM (
SELECT DISTINCT userID
FROM table1
WHERE date > '1/1/2009'
) du
JOIN table2 t2
ON t2.userID = du.userID
AND t2.question = 'Unit'
GROUP BY
answer