How to use outer query column inside inner query column - sql

I am trying to run postgresql query below
SELECT *
FROM user_follow uf
INNER JOIN (SELECT uplr.post, COUNT(*)
FROM user_post_like_relation uplr
WHERE uplr.category = 'like' AND uf.recently_viewed < uplr.created_at . //CANNOT reference uf
AND clicked = true
GROUP BY uplr.post) uplr
ON uplr.post = uf.post
INNER JOIN post p ON uf.post = p.id
Unfortunately I am not able to reference uf inside the INNER JOIN query but it is essential that I join and also reference the recently_viewed column in side the JOIN query. Is there a way of overcoming this?

I think it is sufficient in your case to just JOIN to the table and GROUP the results to perform COUNT.
SELECT uf.post, p.id, count(*)
FROM user_follow uf
JOIN post p ON uf.post = p.id
JOIN user_post_like_relation uplr ON uplr.post = uf.post
WHERE uplr.category = 'like'
AND clicked = 'true'
AND uf.recently_viewed < uplr.created_at
GROUP BY uf.post, p.id
Play with SELECT and GROUP BY columns to get ones which you need.

You have to use INNER JOIN LATERAL if you want to reference columns from previous FROM list entries.
This is available from PostgreSQL 9.3 on.

Related

Outer Join and Inner Join

I used inner join and outer join the following query. When executing this query I get duplicate records. How can I get unique results?
Select *
From DeliveryOrderMaster
Inner Join DeliveryOrder ON DeliveryOrderMaster.VoucherNo = DeliveryOrder.DONo
Inner Join Customer ON DeliveryOrderMaster.Code = Customer.ar_code
Left Outer Join tblbatchSerialNos On DeliveryOrder.DoNo = tblbatchSerialNos.VoucherNo And DeliveryOrder.StockCode = tblbatchSerialNos.ProductCode
Where DeliveryOrderMaster.VoucherNo= 'DO01304'
ORDER BY DeliveryOrder.DoNo ASC,DeliveryOrder.ID ASC
The problem there arent inner or left join. The problem can be the type of table. Are you sure that you have used the correct key to Connect table? Can you give an example of wath return the query?

SQL QUERY data reading

I have two table country and Users. I want to view the country name which have user disabled. So i wrote query for this.
SELECT DISTINCT cntr_id,cntr_name FROM
(SELECT COUNTRY.cntr_id, COUNTRY.cntr_name, USERS.user_enabled,
USERS.user_name, USERS.user_id
FROM COUNTRY INNER JOIN Users
ON COUNTRY.cntr_id = USERS.cntr_id
)
AS TAB where user_enabled = 0
My questions are :
Is this inner query?
will the query fetch all the countries (include user enabled) from the database before running outer query?
Is there any other method to select?
Yes it's an inner Query and will fetch what you need, but you don't need your outer SELECT query. You could just do it like:
SELECT DISTINCT COUNTRY.cntr_id, COUNTRY.cntr_name
FROM COUNTRY INNER JOIN Users
ON COUNTRY.cntr_id = USERS.cntr_id
WHERE USERS.user_enabled = 0
Yes, that is inner query.
Yes, inner query will fetch all the countries (including user enabled). Outer query will remove those records later.
You don't have to use outer query for this.
SELECT DISTINCT C.cntr_id, C.cntr_name
FROM COUNTRY C INNER JOIN
Users U ON C.cntr_id = U.cntr_id
WHERE U.user_enabled=0
OR
SELECT C.cntr_id, C.cntr_name
FROM COUNTRY C INNER JOIN
Users U ON C.cntr_id = U.cntr_id
WHERE U.user_enabled=0
GROUP BY C.cntr_id, C.cntr_name
To answer your question,
Yes It is inner and outer two queries.
The inner query will fetch the all rows which satisfy the join condition.
Yes there is other method to select where you can directly apply the filter in inner query and remove the outer select.
SELECT COUNTRY.cntr_id, COUNTRY.cntr_name, USERS.user_enabled,
USERS.user_name, USERS.user_id
FROM COUNTRY INNER JOIN Users
ON COUNTRY.cntr_id = USERS.cntr_id
WHERE
USERS.user_enabled = 0

Transact SQL JOIN

I have the following query:
SELECT MS.idReg, MS.dsMotivo, A.contrato FROM MS
INNER JOIN S
ON S.motivoSiniestro = MS.idReg
INNER JOIN C
ON C.n__contrat = S.n__contrat
INNER JOIN A
ON A.n__article = C.n__article
Table MS has only 12 records, the ones I need and others have many more entries.
My problem is that I only want the 12 records from MS and their contrato column but I'm getting much more that that. Have tried many combinations of INNER, OUTER, LEFT and RIGHT joins. Any help?
You get too many records because there are several A.contrato values for each row in the MS table. Sql server does not know which one of all the A.contrato values to take so it returns all of them. First you need to decide which one you want.
If any will do you can simply write your query like this:
SELECT MS.idReg, MS.dsMotivo, MAX(A.contrato)
FROM MS
INNER JOIN S
ON S.motivoSiniestro = MS.idReg
INNER JOIN C
ON C.n__contrat = S.n__contrat
INNER JOIN A
ON A.n__article = C.n__article
GROUP BY MS.idReg, MS.dsMotivo
Try this one -
SELECT MS.idReg, MS.dsMotivo, A.contrato
FROM dbo.MS
OUTER APPLY (
SELECT TOP 1 A.contrato
FROM dbo.S
JOIN dbo.C ON C.n__contrat = S.n__contrat
JOIN dbo.A ON A.n__article = C.n__article
WHERE S.motivoSiniestro = MS.idReg
) s

Left outer join and group by issue

I wrote a query. this query sum fields from 2 different table. And grouped by main table id field. But second left outer join is not grouped and giving me different results.
SELECT s.*,
f.firma_adi,
sum(sd.fiyat) AS konak,
sum(ss.fiyat) AS sponsor
FROM fuar_sozlesme1 s
INNER JOIN fuar_firma_2012 f
ON ( s.cari = f.cari )
LEFT OUTER JOIN fuar_sozlesme1_detay sd
ON ( sd.sozlesme_id = s.id )
LEFT OUTER JOIN fuar_sozlesme1_sponsor ss
ON ( ss.sozlesme_id = s.id )
GROUP BY s.id
ORDER BY s.id DESC
I know, it is really complicated but I'm stucking on this issue.
My question is: why second left outer join is not correctly sum of field . If I remove second left outer join or first, everything is normal.
The problem is that you have multiple dimensions on your data, and the number of rows is multiplying beyond what you expect. I would suggest that you run the query for one id, without the group by, to see what rows the join is producing.
One way to fix this is by using correlated subqueries:
select s.*, f.firma_adi,
(select SUM(sd.fiyat)
from fuar_sozlesme1_detay fd
where sd.sozlesme_id = s.id
) as konak,
(select SUM(ss.fiyat)
from fuar_sozlesme1_sponsor ss
where (ss.sozlesme_id = s.id)
) as sponsor
from fuar_sozlesme1 s inner join
fuar_firma_2012 f
on (s.cari = f.cari)
order by s.id DESC
By the way, you appear to by using MySQL (because your query is not parsable in any other dialect). You should tag your questions with the version of the database you are using.

i want to modify this SQL statement to return only distinct rows of a column

select
picks.`fbid`,
picks.`time`,
categories.`name` as cname,
options.`name` as oname,
users.`name`
from
picks
left join categories
on (categories.`id` = picks.`cid`)
left join options
on (options.`id` = picks.oid)
left join users
on (users.fbid = picks.`fbid`)
order by
time desc
that query returns a result that like:
my question is.... I would like to modify the query to select only DISTINCT fbid's. (perhaps the first row only sorted by time)
can someone help with this?
select
p2.fbid,
p2.time,
c.`name` as cname,
o.`name` as oname,
u.`name`
from
( select p1.fbid,
min( p1.time ) FirstTimePerID
from picks p1
group by p1.fbid ) as FirstPerID
JOIN Picks p2
on FirstPerID.fbid = p2.fbid
AND FirstPerID.FirstTimePerID = p2.time
LEFT JOIN Categories c
on p2.cid = c.id
LEFT JOIN Options o
on p2.oid = o.id
LEFT JOIN Users u
on p2.fbid = u.fbid
order by
time desc
I don't know why you originally had LEFT JOINs, as it appears that all picks must be associated with a valid category, option and user... I would then remove the left, and change them to INNER joins instead.
The first inner query grabs for each fbid, the FIRST entry time which will result in a single entity for the FBID. From that, it re-joins to the picks table for the same ID and timeslot... then continues for the rest of the category, options, users join criteria of that single entry.
2 options, you could write a group by clause.
Or you could write a nested query joined back to itself to get pertinent info.
Nested aliased table:
SELECT
n.fBids
FROM
MyTable t
INNER JOIN
(SELECT DISTINCT fBids
FROM MyTable) n
ON n.ID = t.ID
Or group by option
SELECT fBId from MyTable
GROUP BY fBID
select picks.`fbid`, picks.`time`, categories.`name` as cname,
options.`name` as oname, users.`name` from picks left join categories
on (categories.`id` = picks.`cid`) left join options on (options.`id` = picks.oid)
left join users on (users.fbid = picks.`fbid`)
order by time desc GROUP BY picks.`fbid`
select
picks.fbid,
MIN(picks.time) as first_time,
MAX(picks.time) as last_time
from
picks
group by
picks.fbid
order by
MIN(picks.time) desc
However, if you want only distinct fbid's you cannot display cname and other columns at the same time.