"WHERE" Statement From Another Table - sql

I have a table of following/followers that has 3 fields:
id , FollowingUserName,FollowedUserName
And I have a table with posts:
id,Post,PublishingUsername
And I need a query which returns certain fields from post
but the "where" will be where:
The PublishingUsernam From The Posts Will Match The FollowedUserName From The Following/Followers Table
And The FollowingUserName Will Be The Logged On UserName.

To just get posts:
select p.* from posts p where p.PublishingUsername in
(select FollowedUsername from followers)
and p.PublishingUsername = LOGGEDINUSER
Or you could use a join:
select p.* from posts p
left join followers f on f.PublishingUsername = p.PublishingUsername
and p.publishingUsername = LOGGENINUSER

You're looking to do a JOIN it looks like. Basically, you want to select from your post table where the publishing username = followed user name, and where followingusername = loggedin name.
Just taking a stab (since I don't have an SQL server here right now), but it might look like:
SELECT * FROM Posts INNER JOIN Following ON Posts.PublishingUsername = Following.FollowedUserName WHERE FollowingUserName = LoggedInName

Without JOIN you can:
SELECT * FROM Posts p, Followers f
WHERE
f.FollowingUserName = 'LoggedInUserName'
AND f.FollowedUserName = p.PublishingUsername

Using cleaner Join Syntax
SELECT *
FROM following f
JOIN posts p ON p.PublishingUsername = f.FollowedUsername
AND f.FollowingUserName = LOGGED_IN;

SELECT 'fields'
FROM TABLE1 INNER JOIN TABLE2
ON TABLE1.FollowedUserName = TABLE2.PublishingUsername
WHERE FollowingUserName = 'myvalue'

Related

Select clause inside IN with TypeORM

I have a pretty simple sql query:
select * from comments c
inner join users u on u.id = c.user_id
where user_id = 1 OR (c.user_id IN (select user_id_one from friends f where user_id_two = 1))
I am having a lot of trouble getting this translated into TypeORM, specifically this part:
c.user_id IN (select user_id_one from friends f where user_id_two = 1)
No where is it clear on how to use the IN operator along with a inner select statement.
You can add a Where statement and inside that add something like this:
query.where((queryBuilder: SelectQueryBuilder<YOUR_ENTITY>) => {
queryBuilder.where('alias.id in' +
queryBuilder.subQuery()
.select('a.id')
.from(YOUR_ENTITY, 'a')
.getQuery(),
)
})
// ...

How do I fix the syntax of a sub query with joins?

I have the following query:
SELECT tours_atp.NAME_T, today_atp.TOUR, today_atp.ID1, odds_atp.K1, today_atp.ID2, odds_atp.K2
FROM (players_atp INNER JOIN (players_atp AS players_atp_1 INNER JOIN (today_atp INNER JOIN odds_atp ON (today_atp.TOUR = odds_atp.ID_T_O) AND (today_atp.ID1 = odds_atp.ID1_O) AND (today_atp.ID2 = odds_atp.ID2_O) AND (today_atp.ROUND = odds_atp.ID_R_O)) ON players_atp_1.ID_P = today_atp.ID2) ON players_atp.ID_P = today_atp.ID1) INNER JOIN tours_atp ON today_atp.TOUR = tours_atp.ID_T
WHERE (((tours_atp.RANK_T) Between 1 And 4) AND ((today_atp.RESULT)="") AND ((players_atp.NAME_P) Not Like "*/*") AND ((players_atp_1.NAME_P) Not Like "*/*") AND ((odds_atp.ID_B_O)=2))
ORDER BY tours_atp.NAME_T;
I'd like to add a field to this query that provides me with the sum of a field in another table (FS) with a few criteria applied.
I've been able to build a stand alone query to get the sum of FS by ID_T as follows:
SELECT tbl_Ts_base_atp.ID_T, Sum(tbl_Ts_mkv_atp.FS) AS SumOfFS
FROM tbl_Ts_base_atp INNER JOIN tbl_Ts_mkv_atp ON tbl_Ts_base_atp.ID_Ts = tbl_Ts_mkv_atp.ID_Ts
WHERE (((tbl_Ts_base_atp.DATE_T)>Date()-2000 And (tbl_Ts_base_atp.DATE_T)<Date()))
GROUP BY tbl_Ts_base_atp.ID_T, tbl_Ts_mkv_atp.ID_Ts;
I now want to match up the sum of FS from the second query to the records of the first query by ID_T. I realise I need to do this using a sub query. I'm confident using these when there's only one table but I consistently get 'syntax errors' when there are joins.
I simplified the first query down to remove all the WHERE conditions so it was easier for me to try and error check but no luck. I guess the resulting SQL will also be easier for you guys to follow:
SELECT today_atp.TOUR, (SELECT Sum(tbl_Ts_mkv_atp.FS)
FROM tbl_Ts_mkv_atp INNER JOIN (tbl_Ts_base_atp INNER JOIN today_atp ON tbl_Ts_base_atp.ID_T = today_atp.TOUR) ON tbl_Ts_mkv_atp.ID_Ts = tbl_Ts_base_atp.ID_Ts AS tt
WHERE tt.DATE_T>Date()-2000 And tt.DATE_T<Date() AND tt.TOUR=today_atp.TOUR
ORDER BY tt.DATE_T) AS SumOfFS
FROM today_atp
Can you spot where I'm going wrong? My hunch is that the issue is in the FROM line of the sub query but I'm not sure. Thanks in advance.
It's difficult to advise an appropriate solution without knowledge of how the database tables relate to one another, but assuming that I've correctly understood what you are looking to achieve, you might wish to try the following solution:
select
tours_atp.name_t,
today_atp.tour,
today_atp.id1,
odds_atp.k1,
today_atp.id2,
odds_atp.k2,
subq.sumoffs
from
(
(
(
(
today_atp inner join odds_atp on
today_atp.tour = odds_atp.id_t_o and
today_atp.id1 = odds_atp.id1_o and
today_atp.id2 = odds_atp.id2_o and
today_atp.round = odds_atp.id_r_o
)
inner join players_atp as players_atp_1 on
players_atp_1.id_p = today_atp.id2
)
inner join players_atp on
players_atp.id_p = today_atp.id1
)
inner join tours_atp on
today_atp.tour = tours_atp.id_t
)
inner join
(
select
tbl_ts_base_atp.id_t,
sum(tbl_ts_mkv_atp.fs) as sumoffs
from
tbl_ts_base_atp inner join tbl_ts_mkv_atp on
tbl_ts_base_atp.id_ts = tbl_ts_mkv_atp.id_ts
where
tbl_ts_base_atp.date_t > date()-2000 and tbl_ts_base_atp.date_t < date()
group by
tbl_ts_base_atp.id_t
) subq on
tours_atp.tour = subq.id_t
where
(tours_atp.rank_t between 1 and 4) and
today_atp.result = "" and
players_atp.name_p not like "*/*" and
players_atp_1.name_p not like "*/*" and
odds_atp.id_b_o = 2
order by
tours_atp.name_t;

Delete with subquery that produces two columns (in Postgresql)

I have to delete a few records that match two columns calculated with a subquery.
I can properly see them with this query:
select * from user_assignments as ua,
(
select user_assignments.user_id as uid,
job_selection as jid
from user_assignments
join job_selections on job_id = jobs.id
join data on job_selections.data_id = data.id
where data.my_column IS NULL
) as sq
where sq.uid = ua.user_id AND ua.job_selection_id = sq.jid;
This works, and I see the 7 assignments I want to delete.
However, deleting is not as easy as changing the SELECT by DELETE...
If I do:
delete from user_assignments as ua,
(
...
) as sq
where sq.uid = ua.user_id AND sq.jid = ua.job_selection_id;
I get:
ERROR: syntax error at or near ","
I've tried quite an assortment of combinations, yet I can't get it to work. I imagine it must be quite simple, but I'm quite a newbie in SQL.
Basically, I have a subquery that properly produces two columns that I can use for a SELECT FROM user_assignments and now I want to DELETE FROM user_assignments the records that I know I can SELECT.
Any hints would be very appreciated. Thank you in advance.
Use in or exists:
delete from user_assignments ua
where exists (select 1
from user_assignments ua2 join
job_selections js
on ua2.job_id = js.id join
data d
on js.data_id = d.id
where d.my_column IS NULL and
ua.user_id = sq.uid and ua.job_selection_id = sq.jid
);
Oh, I got it (I think).
Kuddos to this tutorial this tutorial and particularly, the section SQL delete records using subqueries with alias.
If someone else is interested, what I did was:
DELETE FROM user_assignments ua
WHERE EXISTS(
SELECT user_assignments.user_id as uid,
user_assignments.job_selection as jid
FROM user_assignments
join job_selections on job_id = jobs.id
join data on job_selections.data_id = data.id
WHERE data.my_column IS NULL
AND ua.user_id = uid
AND ua.job_selection = jid
)
This query also works fine with SELECT * FROM user_assignments

How to Distinct a sql query but still return all columns

This is my query:
SELECT dbo.Webs.Id, dbo.Webs.Title, dbo.Webs.FullUrl, dbo.Roles.RoleId,
dbo.Roles.Title AS RoleTitle, dbo.UserInfo.tp_Title, dbo.UserInfo.tp_Login
FROM dbo.RoleAssignment
INNER JOIN dbo.Roles ON dbo.RoleAssignment.SiteId = dbo.Roles.SiteId
AND dbo.RoleAssignment.RoleId = dbo.Roles.RoleId
INNER JOIN dbo.Webs ON dbo.Roles.SiteId = dbo.Webs.SiteId
AND dbo.Roles.WebId = dbo.Webs.Id
INNER JOIN dbo.UserInfo ON dbo.RoleAssignment.PrincipalId = dbo.UserInfo.tp_ID
WHERE tp_Title = 'HOBSON, Will';
This database contains all the permissions for the users of all sharepoint sites. I'm trying to create a query that displays all sites the user has access to. Currently it outputs a lot of duplicate information. I only want it to display results that have either a distinct Role Title or a distinct Web id.
So for example, in this query I would only want to see 4 results; 1, 5, 11 and 13.
(all this information is on a local test SharePoint installation that cannot be accessed externally, so the only information I'm giving away here is my name :))
Your query would be much easier to read with table aliases. The direct answer to your question is to use SELECT DISTINCT:
SELECT DISTINCT w.Id, w.Title, w.FullUrl, r.RoleId, r.Title AS RoleTitle,
ui.tp_Title, ui.tp_Login
FROM dbo.RoleAssignment ra INNER JOIN
dbo.Roles r
ON ra.SiteId = r.SiteId AND
ra.RoleId = r.RoleId INNER JOIN
dbo.Webs w
ON r.SiteId = w.SiteId AND
r.WebId = w.Id INNER JOIN
dbo.UserInfo ui
ON ra.PrincipalId = ui.tp_ID
WHERE tp_Title = 'HOBSON, Will';
However, it would be better to find the cause of the duplicates. Often duplicates like this are caused by incomplete join conditions. Fixing the join is the better approach, but sometimes SELECT DISTINCT is necessary.
You can just add a DISTINCT to your query:
SELECT DISTINCT dbo.Webs.Id, dbo.Webs.Title, dbo.Webs.FullUrl, dbo.Roles.RoleId,
dbo.Roles.Title AS RoleTitle, dbo.UserInfo.tp_Title, dbo.UserInfo.tp_Login
FROM dbo.RoleAssignment
INNER JOIN dbo.Roles ON dbo.RoleAssignment.SiteId = dbo.Roles.SiteId
AND dbo.RoleAssignment.RoleId = dbo.Roles.RoleId
INNER JOIN dbo.Webs ON dbo.Roles.SiteId = dbo.Webs.SiteId
AND dbo.Roles.WebId = dbo.Webs.Id
INNER JOIN dbo.UserInfo ON dbo.RoleAssignment.PrincipalId = dbo.UserInfo.tp_ID
WHERE tp_Title = 'HOBSON, Will';

Convert sub-query with "NOT IN" operator to join with multiple tables

I need to convert the following sub-query to JOIN. Here I already have JOIN operator in the inner query. Please help.
SELECT *
FROM Consultants
WHERE Consultants.ConsIntID
NOT IN (SELECT Links.ToID
FROM Links JOIN Reminders
ON Links.FromID = Reminders.RemIntID
AND ApptSubType = 'Placed'
AND ToID LIKE 'CS%')
Alright so you probably shouldn't change this to a join I would use NOT EXISTS the reasons for doing so are stated here
I've also replace your ancient join syntax and added aliases to clear this up. The method shown below has been the accepted standard for about 22 years now and is the preferred way to write queries.
SELECT C.*
FROM Consultants as C -- aliases are very useful for clarity
WHERE
NOT EXISTS (
SELECT 1
FROM Links as L
INNER JOIN Reminders as R --New join syntax
ON L.FromID = R.RemIntID
WHERE C.ConsIntID = L.ToID
AND ApptSubType = 'Placed'
AND ToID LIKE 'CS%'
)
SELECT *
FROM Consultants
WHERE Consultants.ConsIntID
NOT IN (SELECT Links.ToID
FROM Links
JOIN Reminders ON(Links.FromID = Reminders.RemIntID)
WHERE ApptSubType = 'Placed'
AND ToID LIKE 'CS%')