Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
I have 5 tables involved in SQL.
conversation_id
staff_id
client_id
summary
1
1
1
conversation between John and Red
1
1
2
conversation between John and Orange
1
2
3
conversation between Kitty and Yellow
1
2
4
conversation between Kitty and Green
staff_id
staff_name
1
John
2
Kitty
client_id
province_id
client_name
1
35
Red
1
81
Orange
1
81
Yellow
1
81
Green
province_id
province_name
35
Toronto
81
Vancouver
division_id
staff_id
province_id
1
1
35
1
1
35
1
2
81
Kitty SHOULD NOT have access to conversation between John & Toronto's Client (client red) because she doesn't have access to Toronto (as shown in the division table).
This is the result from code below:
staff_name
province_name
client_name
summary
John
Vancouver
Red
conversation between John and Red
John
Vancouver
Orange
conversation between John and Orange
Kitty
Vancouver
Yellow
conversation between Kitty and Yellow
Kitty
Vancouver
Green
conversation between Kitty and Green
Here's my code.
SELECT
conversation.conversation_id,
conversation.staff_id,
conversation.client_id,
conversation.summary,
staff.name as staff_name,
client.name as client_name,
province.name as province_name
FROM conversation
LEFT JOIN staff
ON staff.staff_id = conversation.staff_id
LEFT JOIN client
ON client.client_id = conversation.client_id
LEFT JOIN province
ON province.id = client.company_province_id
INNER JOIN division
ON division.province_id = client.province_id
WHERE staff_id = 2
What is wrong?
How I can achieve my goal of making the first row disappear?
Related
There is lot of questions on merging SQL results. Here is my case that has two different SQL results.
userID Car
1 Ford
2 Honda
3 Toyota
userID Color
1 Red
2 Silver
3 White
Is there a way to merge both of the above into the follows in SQL:
userID Car Color
1 Ford Red
2 Honda Silver
3 Toyota White
This looks like a join:
select ca.user_id, ca.car, co.color
from cars ca join
colors co
on ca.user_id = co.user_id;
I probably haven't explained this very well in the title but I have two tables. Here is a simple version.
channel_data
entry_id channel_id first_name last_name model other_fields
1 4 John Smith
2 4 Jane Doe
3 4 Bill Evans
4 15 235
5 15 765
6 15 543
7 15 723
8 15 354
9 15 976
10 1 xxx
11 2 yyy
12 3 123
channel_titles
entry_id author_id channel_id
1 101 4
2 102 4
3 103 4
4 101 15
5 101 15
6 101 15
7 102 15
8 102 15
9 103 15
10 101 1
11 102 2
12 103 3
I am not able to re-model the data unfortunately.
I need to list all the rows with a channel_id 15 from channel_data and beside them the first_name and last_name which has the same author_id from channel_titles.
What I want to return is this:
Model First Name Last Name
---------------------------------
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
If Model was in one table and Names were in another this would be much simpler but I'm not sure how to go about this when they are in the same table.
========================================
Edited to clarify.
I need to get each model with a channel_id 15 from channel_data
For each model I need to look up the entry_id in channel_titles to find the author_id
I need to find the row with that author_id AND channel_id 4 in channel titles (each row with channel_id 4 has a unique author_id).
I need to take the entry_id of this row back to channel_data and get the first_name and last_name to go with the model.
I am well aware that the data is not structured well but that is what I have to work with. I am trying to accomplish a very small task in a much larger system, remodelling the data is not an option at this point.
I think sub-queries might be what I am looking for but this is not my area at all usually.
Ok, that is convoluted. However, based on your description, this query should give you the results you want. The WHERE and JOIN descriptions follow the logic you have described in your question.
SELECT cd1.model, cd2.first_name, cd2.last_name
FROM channel_data cd1
JOIN channel_titles ct1 ON ct1.entry_id = cd1.entry_id
JOIN channel_titles ct2 ON ct2.channel_id = 4 AND ct2.author_id = ct1.author_id
JOIN channel_data cd2 ON cd2.entry_id = ct2.entry_id
WHERE cd1.channel_id = 15
ORDER BY cd1.entry_id
Output:
model first_name last_name
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
Demo on SQLFiddle
Table 1
Customer id city
John 1 LA
Nancy 2 NULL
Table 2
Customer $ in the pocket
John 20
Nancy 30
I am wondering what happen if Table 1 natural join with Table 2? My guess is that the result would be 4 attributes and both John and Nancy will appear.
But my friend told me that only John will appear, Nancy won't because there is a null value.
In the case above, your friend is wrong, you are right!
Let's see a case where it would be otherwise:
Table 'Customer'
Id Name AccNo
1 John 44
2 Nancy NULL
Table 'Account'
AccNo $_in_Pocket
44 20
45 30
Here, with a natural join, we would get all attributes for John but Nancy would be missing from the results.
Suppose I have this table with customer orders:
orderid Name Email Address_1 Address_2 City* Zip*
---------------------------------------------------------------------------
1 James j#j.com 12 Foo St Fooville 1001
2 Alice a#a.com 92 Bla Road Sville 3933
3 James j#j.c0m 12 Foo Street Fooville 1001
4 james king j#j.com 12 Foo St Fooville 1001
5 Anth ann#h.com 12 Foo Street Stacker 2932
6 James j#j.com 12 American St GiftCity 0283
To save postage costs (for us), it would be ideal if we could send multiple orders going to the same person, to the same address in one print slip. For this, I need a unique record for id 1, 3, 4.
The City and Zip codes cannot be entered by the user (selected from a drop down).
Ideally, I would like the following to be returned by my query:
orderid Name Email Address_1 Address_2 City* Zip* Count
---------------------------------------------------------------------------
1 James j#j.com 12 Foo St Fooville 1001 3
2 Alice a#a.com 92 Bla Road Sville 3933 1
5 Anth ann#h.com 12 Foo Street Stacker 2932 1
Essentially, the SQL algorithm is doing a group by on similar on the following columns: Name, Email, concat(Address_1 and Address_2).
Any advice and solutions would be highly appreciated.
If there is a way to do a
GROUP BY similar((concat(name,email,address_1)
(really sorry about the hopeless pseudo-code.. just trying to get my thoughts across).
Well instead of discussion here is a query modify according to your requirements
select
orderid ,
name ,
email ,
address_1 ,
address_2 ,
city ,
zip ,
count(orderid)
from test
group by name
order by orderid
Brings out this
Name Email Address_1 Address_2 City Zip Count
1 James j#j.com 12 Foo St Fooville 1001 3
2 Alice a#a.com 92 Bla Road Sville 3933 1
4 James King j#j.com 12 Foo St Fooville 1001 1
5 Anth ann#h.com 12 Foo St Stacker 2932 1
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have the following tables and data: Screenshot of the data here
course:
course# ctitle units
--------- ------------------- -----
ACCT 201 Financial Account 3
CHEM 356 Organic Chemistry 4
HIST 101 US History 5
MINS 235 Database Design 4
MINS 301 Intro to Business IS 3
MINS 350 Systems Analysis 4
PHED 434 Advanced Gym 2
class:
class# course# sec# semyr
------ ---------- ----- -----
203 ACCT 201 03 F11
204 ACCT 201 04 F11
307 MINS 301 07 F11
418 MINS 235 04 F11
438 MINS 350 01 F11
624 PHED 434 02 F11
student:
sid sname major
--- ---------- ----------
1 Bob MINS
2 Mary POMG
3 Joe MGMT
4 Sue MKTG
5 Jim ACCT
class_student:
class sid grade
----- ---- -----
203 2 B
203 5 D
204 1 C
204 4 C
307 1 B
307 2 B
307 4 A
418 1 A
418 2 B
418 5 C
438 1 B
438 4 C
634 5 F
grade:
grade grade_pts
----- ---------
A 4
B 3
C 2
D 1
F 0
When I run the following query:
SELECT *
FROM STUDENT
WHERE SID NOT IN
( SELECT SID
FROM CLASS_STUDENT
WHERE GRADE IN ('A' , 'B')
)
ORDER BY SID;
I think Oracle would generate this output.
sid sname major
--- ----- -----
1 bob mins
4 sue mktg
5 jim acct
5 jim acct
5 jim acct
I would like to understand how NOT IN logical operator works. How does the NOT IN operator work in the above query to generate the output?
It returns students with grades worse than B.
NOT IN filters out what you define after that.
In words:
select all student but not the ones that have grades A or B
SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' )
will select the sid of the students having A,B grades.
will result in a list of sid
SID
2
1
2
4
1
2
1
then
SELECT * FROM STUDENT
WHERE SID NOT IN ...
will result in :
SID sname Major
3 joe mgmt
5 jim acct
The subquery (SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' )) selects the SIDs of all students that have an A or B grade in at least one class. When used with an IN operator, the list is implicitly deduplicated. It appears in your data that students 1, 2, and 4 all have an A or B in at least one class, so would be included in the result set of this subquery.
Then, the full query is simply selecting all rows from STUDENT that are not included in the list returned by the subquery. So I think you are getting two rows, with SIDs 3 and 5.
Your "expected result" makes little sense. There is no reason to expect multiple rows for the same student when your query is selecting all students then filtering some out.
What your query is doing is showing students that don't have an A or B grade in at least one class. I suspect that what you want is to show each student-class combination for which the grade is worse than a B (that seems consistent with your expected result). To do this, I would suggest driving the query off of the CLASS_STUDENT table, and joining to STUDENT to get the student information (and perhaps to CLASS and COURSE to get the name of the course, if desired).