Hello I would like to retrieve the name and the first name in the user table thanks to the id contained in the message table (id_receive and id_send) in sql via a subquery
SELECT user.nom FROM user
WHERE user.id IN (
SELECT message.id_send, message.id_receive FROM message WHERE message.id=1
)
```
I would recommend using EXISTS, twice:
SELECT u.nom
FROM user u
WHERE EXISTS (SELECT 1 FROM message m WHERE m.id = 1 AND u.id = id_send) OR
EXISTS (SELECT 1 FROM message m WHERE m.id = 1 AND u.id = id_receive) ;
However, a JOIN might also be appropriate:
SELECT u.nom
FROM user u JOIN
message m
ON u.id IN (m.id_send, id_receive)
WHERE m.id = 1;
I suspect it isn't actually what you want but it looks like this is what you're trying to do:
SELECT user.nom FROM user
WHERE user.id IN (
SELECT message.id_send FROM message WHERE message.id=1
UNION ALL
SELECT message.id_receive FROM message WHERE message.id=1
)
The query that drives the IN should return a single column of values
Try and conceive that in works like this:
SELECT * FROM t WHERE c IN(
1
2
3
)
Not like this:
SELECT * FROM t WHERE c IN(
1 2 3
)
Nor like this:
SELECT * FROM t WHERE c IN(
1 2 3
4 5 6
)
It might help you reember that the query inside it must return a single column, but multiple rows, all of qhich are searched for a matching value c by IN
Small addition to your original query to make it working:
SELECT user.nom FROM user
WHERE user.id IN (
SELECT unnest(array[message.id_send, message.id_receive])
FROM message
WHERE message.id=1
)
I'm trying to run this query but no matter what I do I keep getting this error and I cannot work it out. Any help would be appreciated.
select
CC.ContactID,
from
Client C
join Contacts CC on CC.ContactID = C.ContactID
where
ClientID In (
Select
ClientID,Sum(Total-allocated) as Bal
from
Main
Where
Total <> Allocated
and NomTypeID < 10
Group By
ClientID
HAVING Sum(Total-allocated) > 10
)
I'm not sure what DB kind you are using (so I also could not test my answer).
But in general when you use IN you need the subquery to return only one column.
So the query should be (removed the Sum(Total-allocated) as Bal):
select
CC.ContactID,
from
Client C
join Contacts CC on CC.ContactID = C.ContactID
where
ClientID In (
Select
ClientID
from
Main
Where
Total <> Allocated
and NomTypeID < 10
Group By
ClientID
HAVING Sum(Total-allocated) > 10
)
Please use below query,
select
CC.ContactID from
Client C
join Contacts CC on CC.ContactID = C.ContactID
join (Select ClientID,Sum(Total-allocated) as Bal from Main Where
Total <> Allocated and NomTypeID < 10
Group By ClientID HAVING Sum(Total-allocated) > 10)) m
on (C.ClientID = m.ClientID);
I have 3 tables. Users(id, fullname), Chats(id, name) and Chats_Participants(chatId, userId). I need to select all the chats in which user with specified id consists. For example:
Chats:
1. 1, 'Test'
Users:
1. 1, 'Test user'
2. 2, 'Test user2'
Chat_Participants:
1. 1(chatId), 1(userId)
2. 1(chatId), 2(userId)
As a result, I need something like this:
1(chatId) 'Test'(chatName) participants(array of users in chat)
First I've wrote this:
select chats.*, json_agg(users) as participants
from chats
inner join chats_participants c2 on chats.id = c2."chatId"
inner join users on c2."userId" = users.id
where users.id = $userId
group by chats.id;
but this query selects only one participant
You can try with array_agg in postgresql. Demo here. Users table is not linked here, printing user id from chat_participants table instead.
SELECT chats.chat_id,chats.name, array_agg(userid order by chats.chat_id)
FROM chats
INNER JOIN chat_participants ON chats.chat_id = chat_participants.chat_id
GROUP BY chats.chat_id,chats.name
You seem to want:
SELECT c.chat_id, c.name,
array_agg(cp.userid order by cp.user_id) as users
FROM chats c INNER JOIN
chat_participants cp
ON c.chat_id = cp.chat_id
GROUP BY c.chat_id, c.name
HAVING SUM( (cp.userid = $userid)::int ) > 0;
This returns only chats that have your user of interest.
My Tables look like this
Table 1 Table 2
Users Options
id name id user_id option
------- --- -------- --------
1 Donald 1 1 access1
2 John 2 1 access2
3 Bruce 3 1 access3
4 Paul 4 2 access1
5 Ronald 5 2 access3
6 Steve 6 3 access1
Now, i want to select join these to find a user which has only access1
If i do something like
select t1.id,t1.name,t2.id,t2.user_id,t2.option
from table1 t1, table2 t2
where t1.id=t2.user_id
and option='access1';
This does not give me unique results, as in the example i need only user_id=3 my data has has these in hundreds
I also tried something like
select user_id from table2 where option='access1'
and user_id not in (select user_id from table2 where option<>'access1')
There have been other unsuccessful attempts too but i am stuck here
You can do this using a EXISTS subquery (technically, a left semijoin):
SELECT id, name
FROM table1
WHERE EXISTS(
SELECT * FROM table2
WHERE table1.id = table2.user_id
AND table2.option = 'access1'
)
If you want only users that have access1 and not any other access, add NOT EXISTS (a left anti-semi-join; there's a term to impress your colleagues!):
AND NOT EXISTS (
SELECT * FROM table2
WHERE table1.id = table2.user_id
AND table2.option <> 'access1'
)
bool_and makes it simple
with users (id,name) as ( values
(1,'donald'),
(2,'john'),
(3,'bruce'),
(4,'paul'),
(5,'ronald'),
(6,'steve')
), options (id,user_id,option) as ( values
(1,1,'access1'),
(2,1,'access2'),
(3,1,'access3'),
(4,2,'access1'),
(5,2,'access3'),
(6,3,'access1')
)
select u.id, u.name
from
users u
inner join
options o on o.user_id = u.id
group by 1, 2
having bool_and(o.option = 'access1')
;
id | name
----+-------
3 | bruce
If you want the user that has only access1, I would use aggregation:
select user_id
from table2
group by user_id
having min(option) = max(option) and min(option) = 'access1';
WITH users(id,name) AS ( VALUES
(1,'Donald'),
(2,'John'),
(3,'Bruce'),
(4,'Paul'),
(5,'Ronald'),
(6,'Steve')
), options(id,user_id,option) AS ( VALUES
(1,1,'access1'),
(2,1,'access2'),
(3,1,'access3'),
(4,2,'access1'),
(5,2,'access3'),
(6,3,'access1')
), user_access_count AS (
SELECT op.user_id,count(op.option) AS access_count
FROM options op
WHERE EXISTS(
SELECT 1 FROM options
WHERE option = 'access1'
)
GROUP BY op.user_id
)
SELECT u.id,u.name
FROM users u
INNER JOIN user_access_count uac ON uac.user_id = u.id
WHERE uac.access_count = 1;
This request gives me the count of the request occurrences where EMAIL occures.
select count(*)
from ADRESS K left outer join ADRESS L
on K.LFDNRSECONDADRESS=L.LFDNR
left outer join ADRESS V
on K.VERLFDNR=V.LFDNR
where ((UPPER(K.EMAIL)= 'my#email.com'
or exists (select ADRESSEMAILADR.LFDNR
from ADRESSEMAILADR
where ADRESSEMAILADR.ADRESSLFDNR=K.LFDNR
and UPPER(ADRESSEMAILADR.EMAIL)=
'my#email.com' )
)) and K.ART='K'
But I also would like go get all occurrences of the column "LFDNR".
Like
3
1234
2345
3456
...
So the first is the count and the followingup are the results of all columns where LFDNR = X.
Of cause I tried
LFDNR, select count(*)
K.LFDNR, select count(*)
And so on...
No luck so far.
If I understand correctly, you want group by:
select k.LFDNR, count(*)
from ADRESS K left outer join
ADRESS L
on K.LFDNRSECONDADRESS = L.LFDNR left outer join
ADRESS V
on K.VERLFDNR = V.LFDNR
where (UPPER(K.EMAIL)= 'my#email.com' or
exists (select ADRESSEMAILADR.LFDNR
from ADRESSEMAILADR
where ADRESSEMAILADR.ADRESSLFDNR = K.LFDNR and
UPPER(ADRESSEMAILADR.EMAIL) = 'my#email.com'
)
) and
K.ART = 'K'
group by k.LFDNR;