we have three tables.
tblA
id(PK) doc_id(fk) mr_id(fk) date
-------- ---------- -------- ---------
1 23 22 2012-05-23
2 24 22 2012-05-23
3 25 21 2012-05-24
4 26 22 2012-05-24
tblB
doc_id(PK) d_name d_segId(FK) mr_id(FK)
------------ ------------- ---------- ----------
1 manish 1 12
23 rahul 2 22
24 paul 1 22
25 jacky 1 21
26 amit 2 22
tblC
seg_id(PK) seg_name seg_color
-------- ---------- --------
1 A_corei red
2 Bcorec green
what i want is all the record from tblA where mr_id=22 and date='2012-05-23' and order by seg_name in tblC
doc_id is referenced to tblB and
on the basis of doc_id, Seg_id is referenced to tblC how to use join in this situation.
It should look like
id doc_id d_name seg_color
-------- --------- --------- ----------
1 23 rahul green
2 24 paul red
try this.
SELECT a.id,b.doc_id,b.d_name,c.seg_color FROM tblB b
INNER JOIN tblA a ON b.doc_id=a.doc_id
INNER JOIN tblC c ON b.d_segId=c.seg_id
WHERE a.mr_id=22
AND a.date='2012-05-23'
SELECT
tblA.id,
tblA.doc_id,
tblB.d_name,
tblC.seg_color
FROM
tblA, tblB, tblC
WHERE
tblA.doc_id = tblB.doc_id
AND
tblB.d_segId = tblC.seg_id
AND
tblA.mr_id = 22
AND
tblA.date = '2012-05-23'
ORDER BY
tblC.seg_name
Related
I have 3 tables and I want to query them and get results based on
Table 1 Team ID .
I think its simple but I failed to work this out.
All I'm trying to do is get their select their data from other tables and group them by TeamID.
The structure of tables is as follows:
Table 1
This table holds the teams entries by PersonID - referenced by PersonID Table, Each team is in one row
[TeamID] Tournament_id Person_1_ID Person_2_ID Person_3_ID Country_ID
--- --------- -------- ---------- --------- --------
1 77789 123 124 125 90
2 77789 126 127 128 95
3 77789 129 130 131 5
.........
Table 2
This is the person table PersonID = Primary Key
[PersonID] Name Dob Email Country_ID
--------- ------- -------- ---------- ------------
123 John 19/03/1992 John#live.com 90
124 Moe 20/10/1995 Moe#live.com 90
125 Sami 10/05/1989 Sami#example.com 90
126 Kim 30/01/1990 Kim#company.com 95
.......
Table 3
Participation table
[ParticipationID] PersonID tournament_id Country_id
----------------- ---------- ------------- -------------
9999901 123 77789 90
9999902 124 77789 90
9999903 125 77789 90
9999904 126 77789 95
9999905 127 77789 95
.......................
How do I get this output
TeamID Tournament_Id Name Country_ID
------ ----------- ----- ------
1 777789 John 90
1 777789 Moe 90
1 777789 Sami 90
2 777789 Kim 95
Something like this:
SELECT t.TeamID
,t.Tournament_Id
,pr.Name
,pr.Country_Id
FROM Team AS t
INNER JOIN Participation AS p ON p.tournament_id = t.Tournament_id
INNER JOIN Person AS pr ON pr.PersonID = p.PersonID
WHERE Tournament_Id = 777789
I am using MySQL. I'm trying to build something and just can't find a solution to a problem.
I am selecting a value from the lookup table based on my table as shown in the below example.
Select Criteria:
my.id<>l.id AND my.route1=l.route1 AND my.route2=l.route2 AND my.utc=l.utc
where my.stime is closest or same as l.stime
ex) my.id=2's col should get the l.id=1, l.etime=7777 since my.id<>l.id and the rest are the same.
ex) my,id=5's col has options l.id=3, l.etime=9999 and l.id=4, l.etime=7979 since my.id<>l.id, my.route=l.route, my.utc=l.utc. Yet, since my.stime=2220 is closer to l.stime=2222 than l.stime=3333 , l.id=3, l.etime=9999 will be chosen.
ex) my,id=6's col example is to select either value if "closest" is the same.
ex) my,id=7's col example is to return NULL when the criteria is not met.
Table: lookup (l.)
id route1 route2 utc stime etime
---|--------|--------|-----|-------|------
1 11 22 111 1111 7777
2 11 22 111 1111 8888
3 22 33 222 2222 9999
4 22 33 222 3333 7979
5 22 33 222 3335 8989
Table: my (my.) | result
id route1 route2 utc stime | l.id l.etime
---|--------|--------|-----|------- |-------|----------|
2 11 22 111 1111 | 1 7777
5 22 33 222 2220 | 3 9999
6 22 33 222 3334 | 4or5 7979or8989
7 22 33 999 9999 | null null
A new table should be created where the result is appended to the last col of my.
Any help is appreciated. Thanks in advance.
This solution is a bit convoluted, but it's a starting point.
First, let's create an auxiliary table:
CREATE TEMP TABLE temp AS
SELECT m.id mid, l.id lid, ABS(l.stime-m.stime) timediff
FROM my m JOIN lookup l
WHERE m.route1 = l.route1 AND m.route2 = l.route2 AND
m.utc = l.utc AND m.id <> l.id;
From this table we can get the minimum timediff for each my.id:
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
Result:
mid mtimediff
---------- ----------
2 0
5 2
6 1
Now we can find which rows in lookup have this stime difference, and choose the smallest id:
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
This is the result:
mid lid
---------- ----------
2 1
5 3
6 4
And finally we use those ids to extract the data from the tables:
SELECT m.id, m.route1, m.route2, m.utc, m.stime, l.id, l.etime
FROM my m JOIN lookup l JOIN (
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
) ON m.id = mid AND l.id = lid;
Giving:
id route1 route2 utc stime id etime
---------- ---------- ---------- ---------- ---------- ---------- ----------
2 11 22 111 1111 1 7777
5 22 33 222 2220 3 9999
6 22 33 222 3334 4 7979
I want to be able to get all the data from table 1 and table 3 below but in addition to this I also want to get the latest application stage from table 2. The latest application stage is determined by getting the max stage_date for each application.
Table 1: applications
id | applicant_id | col_x | col_y | col_z
-----------------------------------------
10 300 a b c
11 310 a b c
12 320 a b c
13 330 a b c
14 340 a b c
Table 2: application_progress
id | application_id | application_stage | stage_date | stage_notes
------------------------------------------------------------------
1 10 DRAFT 2013-01-01 (NULL)
2 10 APPLICATION 2013-01-14 (NULL)
3 10 PHASE1 2013-01-30 (NULL)
4 11 DRAFT 2013-01-01 (NULL)
4 12 DRAFT 2013-01-01 (NULL)
5 13 DRAFT 2013-01-01 (NULL)
6 14 DRAFT 2013-01-01 (NULL)
7 14 APPLICATION 2013-01-14 (NULL)
EDIT: third table
Table 3: applicants
id | applicant_name | applicant_address | programme_id
------------------------------------------------------
300 Applicant 1 abc 1
310 Applicant 2 xyz 2
320 Applicant 3 xyz 2
330 Applicant 4 xyz 2
340 Applicant 5 xyz 2
Returned data set
applicant_id | applicant_name | current_stage
---------------------------------------------------------
300 Applicant 1 PHASE1
310 Applicant 2 DRAFT
320 Applicant 3 DRAFT
330 Applicant 4 DRAFT
340 Applicant 5 APPLICATION
Am struggling with this one and would appreciate any help.
PS. Tried to put an example of sqlfiddle but it's down at the minute. I'll update this with the sqlfiddle when it's back up if haven't had an answer before this.
You can do this with a correlated subquery:
select a.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a;
EDIT:
You can joining in the applicant data with something like this::
select a.*, aa.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a join
applicant aa
on a.applicant_id = aa.id;
On a MySQL database, I have the table below
package_content :
id | package_id | content_number | content_name | content_quality
1 99 11 Yellow 1
2 99 22 Red 5
3 101 11 Yellow 5
4 101 33 Green 5
5 101 44 Black 5
6 120 11 Yellow 5
7 120 55 White 5
8 135 66 Pink 5
9 135 99 Orange 5
10 135 11 Yellow 5
and i am looking a possibility to make search queries on it:
I would like to select the package_id where content_number could be 11 AND 22 (In this case it should select only package_id 99
I really don't know if it's possible in SQL since the statement AND will always results as false. If i use the statement OR i also get the package_id 99, 101, 120, 135 and that's not what i want.
Maybe my table is not well designed too, but any suggestions would help!
Thanks in advance
Edit
I added the content_quality column
I used the sql query from juergen, works very well
select package_id
from package_content
where content_number in (11,22)
group by package_id
having count(distinct content_number) = 2
My last question is how could i now add another criteria : Select the package_id where content_number is 11 and 22 and content_number 11 has content_quality 1
Edit 2:
For the 2nd question i use now this query. Thanks to both of you who helped me! :)
SELECT *
FROM (
SELECT package_id
FROM package_content
WHERE
(content_number=11 AND content_quality > 1)
OR (content_number = 33 AND content_quality = 5)
OR (content_number = 44 AND content_quality =5 AND content_name like 'Black')
GROUP BY package_id
HAVING count( DISTINCT content_number) = 3
)t1
LEFT JOIN package_content ON package_content.package_id = t1.package_id
This will output
id | package_id | content_number | content_name | content_quality
3 101 11 Yellow 5
4 101 33 Green 5
5 101 44 Black 5
You need to group by the package_id and then use having to perform an aggregate function over the grouped data
select package_id
from package_content
where content_number = 22
or
(
content_number = 11 and content_quality = 1
)
group by package_id
having count(distinct content_number) = 2
You could query with a self join for that:
SELECT DISTINCT package_id
FROM package_content a, package_content b
WHERE a.package_id = b.package_id
AND a.content_number = 11 AND b.content_number = 22
Edit: For your second question: Just add that to the query. The package_content renamed to a is responsible for the content_number 11. Therefore you can ask, wether a has content_quality 1:
SELECT DISTINCT package_id
FROM package_content a, package_content b
WHERE a.package_id = b.package_id
AND a.content_number = 11 AND b.content_number = 22
AND a.content_quality = 1
I want to left join 2 tables.
So all attributes of left table should be shown in result table, no matter if it can join with other table or not.
When I do the follwing, I dont get the expected result
week_table:
date kw note
---------- -- ----
2012-04-01 0 NULL
2012-04-02 0 NULL
fact_table:
id number_of_application number_of_cluster number_of_jvm number_of_node number_of_was fk_wasversion fk_date fk_domain fk_osname fk_osarch fk_osversion fk_stage
-- --------------------- ----------------- ------------- -------------- ------------- ------------- ---------- --------- --------- --------- ------------ --------
1 114 8 80 18 18 6.0 2012-04-01 domain1 Linux sparc 2 stage1
2 114 8 80 18 18 6.0 2012-04-02 domain1 Linux sparc 2 stage1
3 114 8 80 18 18 6.0 2012-04-01 domain1 AIX sparc 2 stage1
4 114 8 80 18 18 6.0 2012-04-02 domain1 Solaris sparc 2 stage1
When I do this:
select
w.date,
coalesce(sum(f.number_of_was), 0)
from
week_table w
left join fact_table f on (w.date = f.fk_date)
where f.fk_osname = "AIX"
group by w.date;
I only get :
date coalesce(sum(f.number_of_was), 0)
---------- ---------------------------------
2012-04-01 18
Expected:
date coalesce(sum(f.number_of_was), 0)
---------- --------------------------------
2012-04-02 18
Does someone know why?
Best Regards
Move the criteria on the outer joined table from the WHERE clause to the ON clause:
select
w.date,
coalesce(sum(f.number_of_was), 0)
from
week_table w
left join fact_table f on (w.date = f.fk_date and f.fk_osname = "AIX")
group by w.date;
where f.fk_osname = "AIX"
I guess there is only one record with this osname?
because of where f.fk_osname = "AIX"
if the data doesnt exist on your right table, it is NULL, and you are asking to retrieve only the rows where fk_osname is = "AIX"`
you can do WHERE (f.fk_osname = "AIX" OR f.fk_osname IS NULL)