I'm trying to make a query that pair a worker that work on the same place. The relational model I'm asking looks like this:
Employee(EmNum, name)
Work(FiNum*, EmNum*)
Field(FiNum, Title)
(bold indicates primary key)
right now my code looks like
SELECT work.finum, e1.name,e1.emnum,e2.name,e2.emnum
FROM employee e1
INNER JOIN employee e2
on e1.EmNum = e2.EmNum
INNER JOIN work
on e1.emnum = work.emnum
This gives me result like
| finum | name | emnum | name_1 | emnum_1 |
| 1 | a | 1 | a | 1 |
| 1 | b | 2 | b | 2 |
| 2 | c | 3 | c | 3 |
| 3 | d | 4 | d | 4 |
| 3 | e | 5 | e | 5 |
while I want the result to be like
| finum | name | emnum | name_1 | emnum_1 |
| 1 | a | 1 | b | 2 |
| 1 | b | 2 | a | 1 |
| 3 | d | 4 | e | 4 |
| 3 | e | 5 | d | 5 |
I'm quite new at sql so I can't really think of a way to do this. Any help or input would be helpful.
Thanks
Your question is slightly unclear, but my guess is that you're trying to find employees that worked on the same place = same finum in work, but different row. That you can do this way:
SELECT w1.finum, e1.name,e1.emnum, e2.name,e2.emnum
from work w1
join work w2 on w1.finum = w2.finum and w1.emnum != w2.emnum
join employee e1 on e1.emnum = w1.emnum
join employee e2 on e2.emnum = w2.emnum
If you don't want to repeat the records (1 <-> 2 + 2 <-> 1 change the != in the join to > or <)
I'm trying to make a query that pair a worker that work on the same place.
Presumably the "places" are represented by the Field table. If you want to pair up employees on that basis then you should be performing a join conditioned on field numbers being the same, as opposed to one conditioned on employee numbers being the same.
It looks like your main join wants to be a self-join of Work to Work of records with matching FiNum. To get the employee names in the result then you will need also to join Employee twice. To avoid employees being paired with themselves, you will want to filter those cases out via a WHERE clause.
Related
I'm using nextcloud to track data via the forms app, the table oc_forms_v2_submissions contains the entries:
SELECT * FROM `oc_forms_v2_submissions` WHERE `form_id` = 3;
+----+---------+--------------------------------------------+------------+
| id | form_id | user_id | timestamp |
+----+---------+--------------------------------------------+------------+
| 8 | 3 | anon-user-96684f301d22e7be44f07780a9bffe06 | 1663789158 |
| 9 | 3 | anon-user-a1eaa4f939b59e00b403c046410788aa | 1663835954 |
| 10 | 3 | anon-user-440d0dbe9c107492b6ec1a06d98004a8 | 1663942458 |
+----+---------+--------------------------------------------+------------+
the second table is oc_forms_v2_answers
SELECT * FROM `oc_forms_v2_answers`;
+----+---------------+-------------+-----------------------+
| id | submission_id | question_id | text |
+----+---------------+-------------+-----------------------+
| 10 | 8 | 7 | foo |
| 11 | 9 | 7 | bar |
| 12 | 10 | 7 | foo |
+----+---------------+-------------+-----------------------+
So basically i need to the take all the id entries from table submissions and match them with submission_id from answers and I want to have the data from the text column.
SELECT oc_forms_v2_submissions.id as submission_id
FROM `oc_forms_v2_submissions`
RIGHT JOIN `oc_forms_v2_answers` ON submission_id=oc_forms_v2_answers.submission_id;
This is all i could come up with so far but that returns only the submission_id field and everything triplicated :-D
+---------------+
| submission_id |
+---------------+
| 8 |
| 8 |
| 8 |
| 9 |
| 9 |
| 9 |
| 10 |
| 10 |
| 10 |
+---------------+
Edit:
The updated query still does not get me the field from oc_forms_answers:
SELECT oc_forms_v2_submissions.id as submission_id
FROM `oc_forms_v2_submissions`
RIGHT JOIN `oc_forms_v2_answers` ON oc_forms_v2_submissions.id=oc_forms_v2_answers.submission_id where form_id="3";
that is because you are comparing to identical columns, you need in the ON Clause, the link columns of both tables
Also you can use alias, to reduce the typing time
The RIGHT JOIN would also combine all answers with thes ubmission, but you you will never have more submission as answer, so a LEFT JOIN would gove ou all submissions even if there is no answer
SELECT oc_forms_v2_submissions.id as submission_id
FROM `oc_forms_v2_submissions`
LEFT JOIN `oc_forms_v2_answers` ON oc_forms_v2_submissions.id=oc_forms_v2_answers.submission_id;
This should do the trick (just update the correct naming of columns and tables)
SELECT s.id as submission_id, a.txt FROM submissions s
LEFT JOIN answers a
ON s.id=a.submission_id;
You can check this here in db-fiddle. I've used your info for creating a DB, so WHERE clause is missing but all the rest should give you results you're after.
I'm bit confused with this problem, I have following table called Member and its structure as follows,
+----------+------+-------------+
| MemberID | Name | ActiveState |
+----------+------+-------------+
| 1 | PAUL | 1 |
+----------+------+-------------+
| 2 | JHON | 1 |
+----------+------+-------------+
| 3 | AMBE | 0 |
+----------+------+-------------+
| 4 | NISH | 1 |
+----------+------+-------------+
And I have another table called ServiceProvided. and its structure as follows. All the member provided data will be saved in this table.
+--------------+-------------+------------+
| ServiceProID | Fkserviceid | FkMemberID |
+--------------+-------------+------------+
| 1 | S1 | 1 |
+--------------+-------------+------------+
| 2 | S2 | 1 |
+--------------+-------------+------------+
| 3 | S1 | 2 |
+--------------+-------------+------------+
| 4 | S3 | 2 |
+--------------+-------------+------------+
Application can soft delete members by changing their active state to 0. I need to get all the ActiveState = 1members data and need to get only if that member has provided any service in the past, should his data be retrieved even if he is deleted. How can I do it.
Expected output is,
ActiveState = 1 and ActiveState = 0 members who has only provided any service in the past
SELECT m.*
FROM Member m
WHERE m.ActiveState = 1
UNION
SELECT m.*
FROM Member m
INNER JOIN ServiceProvided s ON m.MemberId = s.FkMemberId
WHERE m.ActiveState = 0;
The easiest way to achieve this is with UNION.
The INNER JOIN on the deleted Member query assures that you will not retrieve a Member who lacks entries in ServiceProvided.
We have various tables pertaining to different entities where we would like to globalize the stored values. We do not know how to proceed technically anymore and are open to any form of help, hints or tips.
Language
ID | Culture | Description |
---+---------+-------------+
1 | EN | English |
2 | FR | French |
3 | ES | Spanish |
Job
ID | Description |
---+-------------+
1 | Doctor |
2 | Firefighter |
JobGlobalization
ID | JobID | Description | Culture |
---+-------+-------------+---------+
1 | 1 | Docteur | FR |
2 | 1 | Doctora | ES |
We attempted to use CROSS JOIN to obtain something of the following:
ID | Description | Culture |
---+-------------+---------+
1 | Doctor | EN |
1 | Doctor | FR |
1 | Doctor | ES |
2 | Firefighter | ES |
2 | Firefighter | ES |
2 | Firefighter | ES |
Query used:
SELECT Job.ID, Job.Description, Language.Culture
CROSS JOIN Language
ORDER BY Job.ID
We experienced with different joins on the child globalization table in order to correlate the entities together, however the results set kept multiplying itself in the wrong way.
We would like that for every parent entity, whether it has any related child entities, a row is selected for every culture in the Language table. The description column will default to the parent entity in the case where there are no associated records in the child table.
The resulting table should be as follows:
ID | Description | Culture |
---+-------------+---------+
1 | Doctor | EN |
1 | Docteur | FR |
1 | Doctora | ES |
2 | Firefighter | EN |
2 | Firefighter | FR |
2 | Firefighter | ES |
We had in mind a condition that would select the 'Description' column from the parent table 'Job' if there were no corresponding record for it in the child table.
e.g.
IIF(JobGlobalization.Description IS NOT NULL, JobGlobalization.Description, Job.Description)
We attempted to use CROSS JOIN to obtain something of the following:
This should produce the result set you describe:
SELECT j.ID, j.Description, l.Culture
FROM Job j CROSS JOIN
Language l
ORDER BY j.ID, l.Culture;
You can insert this into JobGlobalization (although you might want to truncate it first). Or you can use CREATE TABLE AS (or the equivalent for your database) to create JobGlobalization from scratch.
You would then need to update this table with the appropriate values for the culture.
I have the following data:
select * from art_skills_table;
+----+------+---------------------------+
| ID | Name | skills |
+----+------+---------------------------|
| 1 | Anna | ["painting","photography"]|
| 2 | Bob | ["drawing","sculpting"] |
| 3 | Cat | ["pastel"] |
+----+------+---------------------------+
select * from computer_table;
+------+------+-------------------------+
| ID | Name | skills |
+------+------+-------------------------+
| 1 | Anna | ["word","typing"] |
| 2 | Cat | ["code","editing"] |
| 3 | Bob | ["excel","code"] |
+------+------+-------------------------+
I would like to write an SQL statement which results in the following table.
+------+------+-----------------------------------------------+
| ID | Name | skills |
+------+------+-----------------------------------------------+
| 1 | Anna | ["painting","photography","word","typing"] |
| 2 | Bob | ["drawing","sculpting","excel","code"] |
| 3 | Cat | ["pastel","code","editing"] |
+------+------+-----------------------------------------------+
I've tried something like SELECT * from art_skills_table LEFT JOIN computer_table ON name. However it doesn't give what I need. I've read about array_cat but I'm having a bit of trouble implementing it.
if the skills column from both tables are arrays, then you should be able to get away with this:
SELECT a.ID, a.name, array_cat(a.skills, c.skills)
FROM art_skills_table a LEFT JOIN computer_table c
ON c.id = a.id
That said, While you used LEFT join in your sample, I think either an INNER or FULL (OUTER) join might serve you better.
First, i wondered why the data are stored in such a model.
Was of the opinion that NoSQL databases lack ability for joins and ...
... a semantic triple would be in the form of subject–predicate–object.
... a Key-value (KV) stores use associative arrays.
... a relational database would be normalized.
A few information about the use case would have helped.
Nevertheless, you can select the data with CONCAT and REPLACE for the desired form.
SELECT art_skills_table.ID, computer_table.name,
CONCAT(
REPLACE(art_skills_table.skills, '}',','),
REPLACE(computer_table.skills, '{','')
)
FROM art_skills_table JOIN computer_table ON art_skills_table.ID = computer_table.ID
The query returns the following result:
+----+------+--------------------------------------------+
| ID | Name | Skills |
+----+------+--------------------------------------------+
| 1 | Anna | {"painting","photography","word","typing"} |
| 2 | Cat | {"drawing","sculpting","code","editing"} |
| 3 | Bob | {"pastel","excel","code"} |
+----+------+--------------------------------------------+
I've used the ID for the JOIN, even though Bob has different values.
The JOIN should probably be done over the name.
JOIN computer_table ON art_skills_table.Name = computer_table.Name
BTW, you need to tell us what SQL engine you're running on.
If this is a stupid question, forgive me, I'm not very familiar with PostgreSQL.
I've collected inventory data from used car dealerships in my area and stored it in a postgreSQL table. I've got a second table with particular details regarding certain makes and models. For example:
The dealership table is structured like so:
-----------------------------------------
| Dealership | Make | Model | Year | ID |
----------------------------------------|
| A | Ford | F250 | 2003 | 1 |
| A | Chevy| Cobalt| 2005 | 2 |
| B | Ford | F250 | 2003 | 1 |
| B | Dodge| Chrgr | 2012 | 3 |
-----------------------------------------
The details table is structured like so:
-----------------------------------------
| ID | DetailA| DetailB| DetailC|
-----------------------------------------
| 1 | data | data | data |
| 2 | data | data | data |
| 3 | data | data | data |
| 4 | data | data | data |
-----------------------------------------
My goal is to retrieve vehicle matches from multiple dealerships and display the appropriate details. In the above example, I would like to see:
-----------------------------------------------------
| Make | Model | Year | DetailA | DetailB | DetailC |
-----------------------------------------------------
| Ford | F250 | 2003 | data | data | data |
-----------------------------------------------------
With this result, I will know that both A and B havea 2003 Ford F250 for sale, and can view the related details of the vehicle.
I've tried many different queries, but most are variations on something like this:
SELECT DISTINCT
dealership_table.make,
dealership_table.model,
dealership_table.year
details_table.detaila,
details_table.detailb,
details_table.detailc
FROM
dealership_table
INNER JOIN
details_table
ON
dealership_table.id = details_table.id
WHERE
dealership_table.dealership = 'A'
OR
dealership_table.dealership = 'B'
However this returns all of the distinct matches from the table where dealership is either A or B. I've tried multiple inner-joins, but I an error complaining details_table is specified multiple times.
If I'm doing something really silly, I apologize. Like I said before, I'm pretty much an SQL noob.
What am I doing wrong? How should I go about retrieving the desired results? Any suggestions, solutions, or advice is greatly appreciated!
You can write:
SELECT dealership_table1.make,
dealership_table1.model,
dealership_table1.year,
details_table.detaila,
details_table.detailb,
details_table.detailc
FROM dealership_table dealership_table1
JOIN dealership_table dealership_table2
ON dealership_table1.make = dealership_table2.make
AND dealership_table1.model = dealership_table2.model
AND dealership_table1.year = dealership_table2.year
JOIN details_table
ON dealership_table.id = details_table.id
WHERE dealership_table1.dealership = 'A'
AND dealership_table1.dealership = 'B'
;
(Note that the FROM dealership_table dealership_table1 and JOIN dealership_table dealership_table2 set up distinct "aliases", so you can use the same table multiple different times in the same query without getting name-conflicts.)
I may be misunderstanding your table layout, but I think you should consider changing to a different structure. Here's what I would propose:
Vehicle:
----------------------------
| ID | Make | Model | Year |
----------------------------
| 1 | Ford | F250 | 2003 |
| 2 | Chevy| Cobalt| 2005 |
| 3 | Dodge| Chrgr | 2012 |
----------------------------
Dealership:
----------------------------
| Dealership | ID | Detail |
----------------------------
| A | 1 | data |
| A | 2 | data |
| B | 1 | data |
| B | 3 | data |
----------------------------
This way you're not storing vehicle information (make/model/year) in more than one place.
Here's how you would write your desired query given the above schema:
SELECT Make, Model, Year, A.Detail, B.Detail, C.Detail
FROM Vehicle V
LEFT OUTER JOIN Dealership A on A.Dealership = 'A' and A.id = V.id
LEFT OUTER JOIN Dealership B on B.Dealership = 'B' and B.id = V.id
LEFT OUTER JOIN Dealership C on C.Dealership = 'C' and C.id = V.id