Subquery SQL for link name and firstname - sql

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
)

Related

Optimizing SQL Cross Join that checks if any array value in other column

Let's say I have a table events with structure:
id
value_array
XXXX
[a,b,c,d]
...
...
I have a second table values_of_interest with structure:
value
x
y
z
a
I want to find id's that have any of the values found in values_of_interest. All else equal, what would be the most performant SQL to make this happen? (I am using BigQuery, but feel free to answer more generally)
My current thought is:
SELECT
DISTINCT e.id
FROM
events e, values_of_interest vi
WHERE
EXISTS(
SELECT
value
FROM
UNNEST(e.value_array) value
JOIN
vi ON vi.value = e.value
)
Few quick options for BigQuery Standard SQL
Option 1
select id
from `project.dataset.events`
where exists (
select 1
from `project.dataset.values_of_interest`
where value in unnest(value_array)
)
Option 2
select id
from `project.dataset.events` t
where (
select count(1)
from t.value_array as value
join `project.dataset.values_of_interest`
using(value)
) > 0
I would write this using exists and a join:
select e.id
from `project.dataset.events` e
where exists (select 1
from unnest(e.value_array) val join
`project.dataset.values_of_interest` voi
on val = voi.value
);

Select Statement with INNER JOIN AND CASE

I'm trying to get sql statement to link from one table to another and use a case (or if) if the user has accesslevel 1 then the statement should be select * from campaigns, whereas if ur not accesslevel 1 u should get the select statement as :
select * from campaigns WHERE campaign_Creator = ${user_ID}
SELECT * FROM campaigns
INNER JOIN users ON campaigns.CAMPAIGN_CREATOR = users.USER_ID
CASE WHEN users.USER_ACCESSLEVEL = 1
THEN SELECT * FROM campaigns
ELSE select * from campaigns WHERE CAMPAIGN_CREATOR = ${user_ID};
How would I go around creating such a statement? I've been trying to look it up but i just get more confused as to how to go around with this.
Perhaps this is what you want?
SELECT * FROM campaigns
INNER JOIN users ON campaigns.CAMPAIGN_CREATOR = users.USER_ID
WHERE users.USER_ACCESSLEVEL = 1
OR CAMPAIGN_CREATOR = ${user_ID};
I agree with the solution of our friend and complementing follow my suggestion.
SELECT *
FROM campaigns
INNER JOIN users ON campaigns.CAMPAIGN_CREATOR = users.USER_ID
AND (users.USER_ACCESSLEVEL = 1 OR (users.USER_ACCESSLEVEL != 1
AND CAMPAIGN_CREATOR = ${user_ID}))

How to get first entry with a value from an hierarchical setting structure?

I have a couple of tables. One table with Groups:
[ID] - [ParentGroupID]
1 - NULL
2 1
3 1
4 2
And another with settings
[Setting] - [GroupId] - [Value]
Title 1 Hello
Title 2 World
Now I'd like to get "Hello" back if I'd query the Title for Group 3
And I'd like to get "World" back if I'd query the Title for Group 4 (And not "Hello" as well)
Is there any way to efficiently do this in MSSQL? At the moment I am resolving this recursively in code. But I was hoping that SQL could solve this problem for me.
Don't knoww the SQL Server syntax but something like the following?
SELECT settings.value
FROM settings
JOIN groups ON settings.groupid = groups.parentgroupid
WHERE settings.setting = 'Title'
AND groups.id = 3
This is a problem we've encountered multiple times in our company. This would work for any case, including when the settings can be set only at some levels and not others (see SQL Fiddle http://sqlfiddle.com/#!3/16af0/1/0 :
With GroupSettings(group_id, parent_group_id, value, current_level)
As
(
Select g.id as group_id, g.parent_id, s.value, 0 As current_Level
From Groups As g
Join Settings As s On s.group_id = g.id
Where g.parent_id Is Null
Union All
Select g.id, g.parent_id, Coalesce((Select value From Settings s Where s.group_id=g.id), gs.value), current_level+1
From GroupSettings as gs
Join Groups As g On g.parent_id = gs.group_id
)
Select *
From GroupSettings
Where group_id=4
I believe the following is what you are seeking. See the sqlfiddle
SELECT vALUE FROM
Groups g inner join Settings s
ON g.ParentGroupId = s.GroupID
WHERE g.ID = 3 -- will return Hello,], set ID = 4 will return World

SQL - Linked information

I have a database table, which a program is about to update. I have taken a snapshot of the table before the program ran and a snapshot afterwards. Here is a sample of the data:
Before update:
JoinReference User
1 User 1
1 User 2
1 User 3
2 User 4
2 User 5
2 User 6
After update:
JoinReference User
3 User 1
3 User 2
3 User 3
4 User 4
4 User 5
5 User 6
I am trying to find all the users that are not linked together after the update. For example, user 1; user 2 and user 3 are linked before and after the update (even though they have a different join reference). User 4 and five are still linked after the update. User 6 is not linked after the update. I am trying to return user 6 after the update. I have tried using derived tables but it has not worked.
This is for a very large database. The example I have given uses fields I have made up to explain the problem. The database structure for the example would be like this:
CREATE TABLE JoinedUsers (JoinReference int, User)
select UnpairedBefore.userid
from
(select main.*
from tableBefore main
left join tableBefore ref
on main.joinreference = ref.joinreference
and main.userid <> ref.userid
where ref.userid null) UnpairedBefore
inner join
(select main.*
from tableAfter main
left join tableAfter ref
on main.joinreference = ref.joinreference
and main.userid <> ref.userid
where ref.userid null) UnpairedAfter
on UnpairedBefore.userid = UnpairedAfter.userid
or
select [user]
from tblBefore
where JoinReference in
(
select JoinReference
from tblBefore
group by JoinReference
having COUNT(*) = 1
)
and [user] in
(
select [user]
from tblAfter
where JoinReference in
(
select JoinReference
from tblAfter
group by JoinReference
having COUNT(*) = 1
)
)
You want something along the lines of
SELECT *
FROM myTable
WHERE (row_was_updated)
AND JoinReference IN
(SELECT JoinReference
FROM myTable
GROUP BY JoinReference
HAVING COUNT(*) = 1)
You may or may not need WHERE (row_was_updated) and you'll have to fill in that logic yourself if you need it.
It's likely there would be a more efficient way of doing that, but without schema it's only possible to give general guidance.
SELECT b1.user AS user1
, b2.user AS user2
FROM BeforeTable AS b1 --- user1 and
JOIN BeforeTable AS b2 --- user2 were linked
ON b1.JoinReference = b2.JoinReference --- before the update
WHERE b1.user < b2.user
AND NOT EXISTS --- and are not linked
( SELECT *
FROM AfterTable AS a1 --- after the update
JOIN AfterTable AS a2
ON a1.JoinReference = a2.JoinReference
WHERE a1.user = b1.user
AND a2.user = b2.user
) ;

Combine a 'Distinct' SQL Query with a single value query

I have an existing sql query that I'd like to apply to every record returned from a "distinct" query.
I guess something like looping through each of the returned records, storing it as a string, and using that value in the other query. How would I go about this?
sudo queries:
Select ...
for each record returned as X,
Select ... etc ... where ... LIKE X
Edit:
not sure how to make it clearer, but I know I'm probably not making it obvious. I'll try:
The distinct will return a single column, with many records. I need to apply each value to the second sql query.
So like.. Select X and Y, but Y is returned from the 2nd query I have, using X
Edit2:
If the distinct select returns
1
2
3
4
And the second query returns a single record "A" when the where clause looks like ... = '1', "B" when the where clause looks like ... = '2', "C" when the where clause looks like ... = '3', and C when the where clause looks like ... = '4'
Then I'd like my final output to look like
1 | A
2 | B
3 | C
4 | C
Edit 3:
first query:
SELECT DISTINCT [user_id] from dbo.sap_empl_subset
second query:
SELECT [name_pref_mixed]
FROM dbo.sap_empl_subset AS E
WHERE E.sap_position_no IN
(SELECT P.sap_position_no
FROM dbo.sap_position AS P
WHERE (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE 'CHIEF%'))
AND E.sap_org_code =
(SELECT
CASE
WHEN S.sap_org_code_level2 = 0 THEN S.sap_org_code
WHEN S.sap_org_code_level3 = 0 THEN S.sap_org_code_level1
ELSE S.sap_org_code_level2
END
FROM dbo.sap_org_structure AS S
WHERE S.sap_org_code =
(SELECT E1.sap_org_code
FROM dbo.sap_empl_subset AS E1
WHERE E1.[user_id] = '<each item from first query needs applied here>'))
SELECT *
FROM (
SELECT DISTINCT value
FROM mytable
) x
JOIN othertable y
ON y.value LIKE '%' || x.value || '%'
Update:
If you first query is
SELECT my_x
FROM mytable
WHERE my_y = '…'
and the second one is
SELECT other_z
FROM othertable
WHERE other_y = my_x
the you just need a join:
SELECT my_x, other_z
FROM mytable
JOIN othertable
ON other_y = my_x
WHERE my_y = '…'
It would be much more easy to answer if you just posted the queries.
Update 2:
Try this:
SELECT es.user_id, esp.name_pref_mixed
FROM sap_empl_subset es
JOIN sap_org_structure os
ON os.sap_org_code = es.sap_org_code
JOIN sap_empl_subset esс
ON esc.sap_org_code =
CASE
WHEN os.sap_org_code_level2 = 0 THEN os.sap_org_code
WHEN os.sap_org_code_level3 = 0 THEN os.sap_org_code_level1
ELSE os.sap_org_code_level2
END
WHERE esc.sap_position_no IN
(
SELECT sap_position_no
FROM sap_position sp
WHERE (LTRIM(RTRIM(sp.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(sp.sap_position_desc)) LIKE 'CHIEF%'))
)
DISTINCT seems to be redundant here. You have a condition in your second query:
WHERE S.sap_org_code =
(
SELECT E1.sap_org_code
FROM dbo.sap_empl_subset AS E1
WHERE E1.[user_id] = '<each item from first query needs applied here>')
)
which would throw an error if there were duplicates on sap_empl_subset.user_id
A join was not necessary to combine the two queries. All I needed was the nested select syntax as shown below, where the first line is the first query, and the first nested select is the second query. A join was not necessary.
SELECT Distinct U.[user_id] AS "User ID", (
SELECT [empl_last_name]
FROM dbo.sap_empl_subset AS E
WHERE E.sap_position_no IN
(SELECT P.sap_position_no
FROM dbo.sap_position AS P
WHERE (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%CHIEF%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[EXECUTIVE ]VP%')
)
AND E.sap_org_code =
(SELECT
CASE
WHEN S.sap_org_code_level2 = 0 THEN S.sap_org_code
WHEN S.sap_org_code_level3 = 0 THEN S.sap_org_code_level1
ELSE S.sap_org_code_level2
END
FROM dbo.sap_org_structure AS S
WHERE S.sap_org_code =
(SELECT E1.sap_org_code
FROM dbo.user_id AS E1
WHERE E1.[user_id] = U.[user_id]))) As "VP"
From dbo.user_id As U WHERE U.[user_id] <> ''
ORDER BY [User ID]