I have 2 tables from which I'm trying to pull data from together in 1 query.
Guilds:
id (int) | guild (varchar)
Challenges:
id (int) | challenger (int) | challengee (int)
The "challenger" and "challengee" fields reference a "id" from the Guilds table. Using one query, I'd like to pull the Guild field for both the "challenger" and "challengee" (based on the "guild id"), but am stuck on the correct syntax to use.
SELECT challenges.`id` AS c_id, challenges.`challengee` AS c_challengee, challenges.`challenger` AS c_challenger, guilds.`guild`
FROM challenges
LEFT JOIN guilds
ON challenges.`challengee` = guilds.`id`
Is it possible building a query that would grab both the "challenger" and "challengee" Guild (field)?
An example of the result I'm trying to achieve:
challenge_id | challenger | challenger_guild | challengee | challengee_guild
------------- ------------- ------------------ -------------- -----------------
2 | 8 | oBsolete | 5 | Plague
try
SELECT Guilds.id
, Guilds.guild
, chas.challenger
, chal.challengee
FROM Guilds
LEFT OUTER
JOIN Challenges as chal
ON chal.challengee = Guilds.id as xxx_challengee
LEFT OUTER
JOIN Challenges as chas
ON chas.challenger = Guilds.id as xxx_challenger
ORDER
BY Guilds.id
not sure if it will work
Here you go:
SELECT t.id, t.challenger, t.g_challenger, t.challengee, g2.guild as g_challengee
FROM (
SELECT c1.id, c1.challenger, g1.guild as g_challenger, c1.challengee
FROM Guilds g1
JOIN Challenges c1
ON g1.id = c1.challenger
) t
JOIN Guilds g2
ON g2.id = t.challengee
Working Fiddle: http://sqlfiddle.com/#!2/e036d0/18
Related
I'm making a search function in PHP and I have three tables that I wish to join to a single one; the three tables looks as follow:
band
ID | bands
---+----------
1 | Muse
2 | Coldplay
3 | etc.
release
ID | releases
---+----------
1 | Showbiz
2 | Origin of Symmentry
3 | etc.
track
ID | tracks
---+-----------
1 | Sunburn
2 | Muscle Museum
3 | etc.
I want these tables to be put into this:
discografic
ID | band_id | release_id | track_id
---+----------+-------------+---------
1 | 1 | 1 | 1
2 | 1 | 1 | 2
3 | etc.
So that the table with the SQL code looks like this:
discografic
ID | bands | releases | tracks
---+----------+-------------+---------
1 | Muse | Showbiz | Sunburn
2 | Muse | Showbiz | Muscle Museum
3 | etc.
I want to INNER JOIN these tables. I joined one but I can't really figure out how the get the last joined as well.
SELECT *
FROM band
INNER JOIN discografic
ON band.id = discografic.band_id
This should probably have its own question; I also want to be able to search this database, but only have the result show up once, and also reference to the band every time. For example, if I search "Showbiz" it will give me "Muse", and only show it once.
Note: This is for testing purposes only, security is none of my concerns.
Try with this query:
select d.id,b.bands,r.releases,t.tracks from discografic as d INNER JOIN band as b on
d.band_id=b.id INNER JOIN release as r on d.release_id=r.id INNER JOIN track as t on
d.track_id=t.id GROUP BY d.id
Try This query
Select a.ID,b.bands,c.releases,d.tracks from discografic as a
inner join band as b on a.band_id = b.ID
inner join release as c on a.release_id = c.ID
inner join track as d on a.track_id = d.ID
where b.bands = 'Muse'
Use this query to insert the data like you wanted:
Insert into discograpy
(id,bands,releases,tracks)
SELECT band.ID,bands,releases,tracks
FROM band
INNER JOIN releases
ON band.id = releases.id
inner join track
on band.id = track.id
Use this query to show you only one band:
Declare #releases varchar(50)
Set #releases = 'showbiz'
SElect distinct bands from discograpy where releases = #releases
Here any variable can be passed or set in place of showbiz. This is an example
I'm having difficulty figuring out how to create the proper syntax for my query.
Here is what i'm pulling. I have 2 tables.
Table 1 : Fields (user_id, name)
Table 2 : Fields (user_id, type, are_code, phone_number).
Table 1 can only have 1 record per user_id.
1 | John Doe
Table 2 can have up to 3 records per user_id:
1 | Home | 123 | 456.4567
1 | Work | 000 | 987.1467
1 | Mobi | 098 | 987.1756
How can i select everything so that my table will result in 1 record pulled like so :
user_id | name | home# | work# | mobi#
I tried this, which duplicates and doubles rows based on amount of entries within Table 2.
SELECT a.user_id,
b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id
That unfortunately returned 3 rows which is not good :(.
1 | John Doe | area | home# |
1 | John Doe | area | work# |
1 | John Doe | area | mobi# |
Any help and or pointers would be greatly appreciated.
Try this out:
SELECT
u.user_id,
u.name,
MAX(CASE WHEN p.type = 'Home' THEN phone_number END) HomeNumber,
MAX(CASE WHEN p.type = 'Work' THEN phone_number END) WorkNumber,
MAX(CASE WHEN p.type = 'Mobi' THEN phone_number END) MobiNumber
FROM phones p
JOIN users u ON p.user_id = u.user_id
GROUP BY u.user_id, u.name
Output:
| USER_ID | NAME | HOMENUMBER | WORKNUMBER | MOBINUMBER |
|---------|----------|------------|------------|------------|
| 1 | John Doe | 456.4567 | 987.1467 | 987.1756 |
Fiddle here.
Also note that you can remove u.name if u.user_id determines u.name... which is most likely the case as it seems to be a primary key. That would speed things up a little bit.
Note: This assumes that you cant have more than one same type for the same user (as it is in your example data, which only has one column for home, work and mobile.
Use user_contact_phones.type to get exact what you want, like-
SELECT a.user_id,
b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id where b.type='Home'
Here's a solution that will work:
select u.user_id, u.name,
thome.area_code as home_area_code, thome.phone_number as home_phone_number,
twork.area_code as work_area_code, twork.phone_number as work_phone_number,
tmobi.area_code as mobi_area_code, tmobi.phone_number as mobi_phone_number
from table1 u
left outer join table2 thome on u.user_id = thome.user_id and thome.type = 'Home'
left outer join table2 twork on u.user_id = twork.user_id and twork.type = 'Work'
left outer join table2 tmobi on u.user_id = tmobi.user_id and tmobi.type = 'Mobi'
Please note the use of left outer join instead of inner join in case the record for a particular type does not exist. You will get null values for those columns in your result set with left outer join. With inner join, you would not get a result for a user that did not have all three types. Good luck!
I have a set of approx 9000 tutor ids in an array and i have put them in a string like:
(1,2, 3, 4,5,6,7,....9000,9001,9002)
so that i can use them in the following query:
select count(student_assignment.assignment_id) as total_assignment from
student_assignment, assigned_tutor_fk where assignment_status = 'closed'
and assigned_tutor_fk in (1,2, 3, 4,5,6,7,..100,101,103...9000,9001,9002)
group by assigned tutor_fk.
I want to calculate total number of rows associated with each tutor(assigned_tutor_fk), and those tutors which do not have an assignment ie those which do not have assignment
record in the table i want to show their assignment count as 0, and i just want my query to return count and assigned_tutor_fk
my table structure is:
assignment_id | assigned_tutor_fk | assignment_date | student_id |
| 1 | 2 | 22-01-2011 | 4 |
| 2 | 3 | 14-03-2011 | 5 |
Im trying to get my output to be like this:
|total_assignment | assigned_tutor_fk |
| 5 | 4 |
| 2 | 7 |
| 0 | 8 |
Update: I tthink i have not been able to express myself properly,i already have a list of tutors filtered on another criteria, it was very complex to combine these two queries so now i have a set of the tutor id's and i want the sum to be displayed as zero in case the tutors does not have assignment record. please help me on this as i don know wht to do now
SELECT t.id, COUNT(sa.assignment_id)
FROM tutor t
LEFT JOIN
student_assignement sa
ON sa.assignment_tutor_fk = t.id
WHERE t.id IN (1, 2, ..., 9002)
GROUP BY
t.id
dont put the tutors in a string. Select them from a table and do a LEFT JOIN with the assignment and FK table. Without knowing all of your tables, i'm guessing it would look like this:
select
t.tutorId,
count(sa.assignment_id) as total_assignment
from
tutor t
LEFT JOIN
assigned_tutor_fk fk
ON
fk.assigned_tutor_fk = tutor.tutorId
LEFT JOIN
student_assignment sa
ON
fk.assignment_id = sa.id
where
sa.assignment_status = 'closed' OR
ISNULL(sa.assignment_status) -- if join fails.
group by
t.tutorId
Left Join retrieves all your values from the tutor table and merges it with the joined table IF there is a match. If not, NULL is inserted.
SELECT
count(*) as total_assignment,
assigned_tutor_fk
FROM assignmentTable
GROUP BY assigned_tutor_fk
I am trying to query 6 separate tables in my mysql database, the structures are as follows;
item
itemitemid | item | description | brand | date | time | path |
actor
actoractorid | name | actorthumb | bio |
brand
brandbrandid | brandname | description | image |
movie
moviemovieid | title | genre | year | moviethumb | synopsis|
users
userid | name | surname | email | password |
request
requestid | userid | itemid | brandid | movieid | actorid | content | requestdate |
Using the following query I can display for example where the requestid=1 I can see the movie in the request, the actor in the movie, the item of clothing they were wearing and its brand.
$requestid = mysql_real_escape_string($_GET['requestid']);
$query = "select r.requestid, m.*, a.*, i.*, b.*
FROM request r INNER JOIN movie m ON m.movieid = r.movieid
INNER JOIN actor a ON a.actorid = r.actorid
INNER JOIN item i ON i.itemid = r.itemid
INNER JOIN brand b ON b.brandid = r.brandid
WHERE r.requestid = $requestid";
However when I try to echo out "content" and "request date" from the request table. The data simply doesn't appear. I also cannot get the info from the user table, e.g the user logging the request by by adding the following join;
$query = "select r.requestid, m., a., i., b., u.*
INNER JOIN users u ON u.userid = r.userid
Please advise?
You aren't SELECTing those fields. Right now, you're only SELECTing r.requestid from the requests table. You need to add references to every field you want to echo.
As far as the User join, you just seem to be joining on the wrong field. You need to join on u.userid = r.userid. Right now, you're joining on u.itemid which doesn't exist. You'll also need to change your SELECT statement to report the fields you want (e.g. SELECT ... , u.name, u.email).
As an aside, you should avoid SELECTing table.* where possible. This can break things when you add a field to a table but don't account for that when processing the results of a query. You should try to be explicit as possible, and SELECT only the fields you want to use - e.g. SELECT users.name, users.email rather than doing SELECT users.*.
I'm creating a site in wordpress which holds information on television programs. I'm using custom fields to select each post.
The table looks something like this
+----+---------+----------+------------+
| id | post_id | meta_key | meta_value |
+----+---------+----------+------------+
| 1 | 1 | name | Smallville |
| 2 | 1 | season | 1 |
| 3 | 1 | episode | 1 |
| 4 | 2 | name | Smallville |
| 5 | 2 | season | 1 |
| 6 | 2 | episode | 2 |
+----+---------+----------+------------+
Basically what I need to do is select all of the tv shows with the name "Smallville" and sort them by season then by episodes. I thought it would be fairly simple but everything I have tried returns nothing.
Could you please explain how I can do this?
You can do something like this:
SELECT
t1.post_id,
t1.meta_value AS name,
t2.meta_value AS season,
t3.meta_value AS episode
FROM
(
SELECT *
FROM the_table
WHERE meta_key = 'name'
) t1
INNER JOIN
(
SELECT *
FROM the_table
WHERE meta_key = 'season'
) t2 ON t1.post_id = t2.post_id
INNER JOIN
(
SELECT *
FROM the_table
WHERE meta_key = 'episode'
) t3 ON t1.post_id = t3.post_id
This will give you the result:
| post_id | name | season | episode |
-------------------------------------------
| 1 | Smallville | 1 | 1 |
| 2 | Smallville | 1 | 2 |
In this form it is much easier for any operations.
What you need is to add:
WHERE name = 'Smallville'
ORDER BY season, episode
Combine the rows using a self-join, and you're good to go:
SELECT *
FROM yourtable name
INNER JOIN yourtable season
on season.post_id = name.post_id
and season.meta_key = 'season'
INNER JOIN yourtable episode
on episode.post_id = name.post_id
and episode.meta_key = 'episode'
WHERE name.meta_key = 'name'
and name.meta_value = 'Smallville'
ORDER BY season.meta_value, episode.meta_value
A more general case: sort-of conversion from your format to a more normal relational DB format:
SELECT (SELECT meta_value FROM data t1 WHERE t1.post_id = t0.post_id AND meta_key = "season") AS season,
(SELECT meta_value FROM data t1 WHERE t1.post_id = t0.post_id AND meta_key = "episode") AS episode
FROM data t0 WHERE meta_key = "name" AND meta_value = "Smallville"
For the actual sorting you can't reuse the season / episode values (those aren't assigned yet while sorting), so you have to copy/paste the subquery into the ORDER BY clause:
ORDER BY (SELECT ... "season") ASC, (SELECT ... "episode") ASC,
No need to do direct SQL.
You've got access to the SQL query through the WP_Query object. Check out the filters surrounding the where clause in the WP_Query object (there is more than 1 way to get at it) and simply modify the default WP_Query parts before they're concatenated together.
Start by setting up a WP_Query object that gets all the posts by postmeta key & postmeta value, and then tack on a bit more to the where clause to do some extra conditionals.
There's another filter that allows you to get at the ordering section of the SQL query so you can modify that.
There's no reason to hand write SQL here, just modify what has already been built for you.
the idea is to join the table to itself 3 times where for each of them take rows for a given meta_key:
SELECT t1.meta_value name, t2.meta_value season, t3.meta_value episode
FROM table t1
JOIN table t2 on t1.post_id = t2.post_id and t2.meta_key = 'season'
JOIN table t3 on t1.post_id = t3.post_id and t3.meta_key = 'episode'
WHERE t1.meta_key = 'name'
AND t1.meta_value = 'Smallville'
ORDER BY t2.meta_value, t3.meta_value