MySQL finding rows in one table with information from another - php

Currently, I have two MySQL tables.
First table stores relation between the friend and his picture.
TABLE 1
id | pic_id | friend_id
----------------------------
0 | 123 | 84589
1 | 290 | 11390
2 | 884 | 84589
TABLE 2
Second table stores more information about the pic...
id | pic_id | title | color | detail
----------------------------------------------
0 | 123 | hello | black | brush
1 | 124 | world | red | paint
2 | 884 | sample | green | star
I have my friend_id and need to grab all the pic_id from Table 1 and then use the pic_id to grab the columns from Table 2(title, color, detail)...
How would I do this in MySQL?
Thank you!

Simply join the two tables.
SELECT b.title, b.color, b.detail
FROM table1 a INNER JOIN table2 b
on a.pic_id = b.pic_id
WHERE friend_id = 84589

Related

Is it possible to combine 4 tables?

I need to query data from 4 tables. I'm not sure this is the best db design to approach this. This is simplified version. The actual table have more column.I have table for users who upload their song:
Id | Username |
---------------
1 | John |
2 | Michael |
3 | Frank |
Then I have song table like this
Id | Title | UserId
----------------------
1 | Title 1 | 1
2 | Title 2 | 1
3 | Title 3 | 2
4 | Title 4 | 2
Then a playlist table like this
Id | Title | UserId
------------------------
1 | My Playlist | 3
Then a playlist entries where a user save song id belong to a playlist
Id | SongId | PlaylistId
--------------------------
1 | 2 | 1
2 | 4 | 1
3 | 3 | 1
What I want to achieve after query is something like this:
Playlist | By | Song List
------------------------------------------------------------
My Playlist | Frank | Title 2 - John, Title 3 - Michael,
| | Title 4 - Michael
-------------------------------------------------------------
Any idea how to query this in MySQL. Or any better table design to achieve same result?
Try this:
SELECT
p.Title as Playlist,
u1.Username as By,
group_concat(s.Title, ' - ', u2.Username order by s.Id) as `Song List`
FROM playlist p
JOIN playlist_entries pe
ON p.Id= pe.PlaylistId
JOIN song s
ON pe.SongId = s.Id
JOIN user u1
ON p.UserId = u1.Id
JOIN user u2
ON s.UserId = u2.Id
Demo Here

How to get COUNT and INNER JOIN related with concated value field in mysql

I have 2 tables
table A
tag_id | Tag_name
1 | tg1
2 | tg2
3 | tg3
4 | tg4
table B
id | name |tag_id
1 | avq | 1,2,4
2 | bdq | 2
3 | abc | 3,2
4 | vdf | 1,4
5 | zxc | 3
I want to inner join both tables and get its count using tag_id in the following format
`tg1=> 2,tg2=> 3,tg3=> 2,tg4=> 2`
How is it possible in a single MySQL query?
The best option is to normalize the 2nd table and create an association table for storing the tag id and the id of the 2nd table. In the meanwhile the following should do the job but for long run you need to normalize the table else more problems will happen in future
select
t1.Tag_name, count(*) as total
from tableA t1
join tableB t2 on find_in_set(t1.tag_id,t2.tag_id) > 0
group by t1.tag_id ;
You need to create relation table. For example:
Tag table:
+----+----------+
| id | name |
+----+----------+
| 1 | Tag name |
+----+----------+
| 2 | Tag 2 |
+----+----------+
B Table:
+----+-----------+
| id | title |
+----+-----------+
| 1 | Any title |
+----+-----------+
Reference table ex. :
+------+--------+
| b_id | tag_id |
+------+--------+
| 1 | 1 |
+------+--------+
| 1 | 2 |
+------+--------+
In your reference table you put many tags for one B element. In this example you see two tags assigned by reference to b_id = 1
select tag_name, count(position)
from (
select a.tag_name, FIND_IN_SET(a.tag_id,b.tag_id) as position
from a,b
) as tmpTB
where position !=0
group by tag_name

SQL: get data spread over 3 tables

I am trying to get some statistics for an online game I maintain. I am searching for an SQL statement to get the result on the bottom.
There are three tables:
A table with teams, each having a unique identifier.
table teams
---------------------
| teamid | teamname |
|--------|----------|
| 1 | team_a |
| 2 | team_x |
---------------------
A table with players, each having a unique identifier and optionally an affiliation to one team by it's unique teamid.
table players
--------------------------------
| playerid | teamid | username |
|----------|--------|----------|
| 1 | 1 | user_a |
| 2 | | user_b |
| 3 | 2 | user_c |
| 4 | 2 | user_d |
| 5 | 1 | user_e |
--------------------------------
Finally a table with events. The event (duration in seconds) is related to one of the players through their playerid.
table events.
-----------------------
| playerid | duration |
|----------|----------|
| 1 | 2 |
| 2 | 5 |
| 3 | 3 |
| 4 | 8 |
| 5 | 12 |
| 3 | 4 |
-----------------------
I am trying to get a result where the durations of all team members is summed up.
result
--------------------------
| teamid | SUM(duration) |
|--------|---------------|
| 1 | 14 | (2+12)
| 2 | 15 | (3+8+4)
--------------------------
I tried several combinations of UNION, WHERE IN, JOIN and GROUP but could not get it right. I am using PostgreSQL and PHP. Can anyone help me?
Just use sum with group by:
select t.teamid, sum(e.duration)
from team t
join players p on t.teamid = p.teamid
join events e on p.playerid = e.playerid
group by t.teamid
If you need all teams to be returned even if they don't have events, then use an outer join instead.
Try this
SELECT teamid, Sum(duration),
AS LineItemAmount, AccountDescription
FROM teams
JOIN teams ON teams.teamid = players.teamid
JOIN events ON players.playersid = events.playersid
JOIN GLAccounts ON InvoiceLineItems.AccountNo = GLAccounts.AccountNo
GROUP BY teamid
http://www.w3computing.com/sqlserver/inner-joins-join-two-tables/

Selecting multiple tables MySQL and retrieving different data

I have 4 tables that I need to pull data from. I need to count how many people are signed for a single event and see if a user is applied for an event.
These are my table setups:
TABLE: users
+----+----------+-------+--------+-------+
| id | username | level | class | guild |
+----+----------+-------+--------+-------+
| 1 | example1 | 100 | Hunter | blah |
| 2 | example2 | 105 | Mage | blah2 |
| 3 | example3 | 102 | Healer | blah |
+----+----------+-------+--------+-------+
ID is primary
TABLE: event_randoms
+----+----------+-------+--------+----------+----------+
| id | username | level | class | apped_by | event_id |
+----+----------+-------+--------+----------+----------+
| 1 | random1 | 153 | Hunter | 3 | 3 |
| 2 | random2 | 158 | Healer | 3 | 1 |
| 3 | random3 | 167 | Warrior| 1 | 3 |
+----+----------+-------+--------+----------+----------+
ID is primary
apped_by should be foreign key to users.id
event_id should be foreign key to events.id
TABLE: events
+----+------------+------------+-----------+-----------+-----------+
| id | event_name | event_date | initiator | min_level | max_level |
+----+------------+------------+-----------+-----------+-----------+
| 1 | event1 | date1 | 1 | 100 | 120 |
| 2 | event2 | date2 | 1 | 121 | 135 |
| 3 | event3 | date3 | 1 | 100 | 120 |
| 4 | event4 | date4 | 1 | 150 | 200 |
+----+------------+------------+-----------+-----------+-----------+
ID is primary
TABLE: event_apps
+----+----------+--------------+
| id | event_id | applicant_id |
+----+----------+--------------+
| 1 | 3 | 2 |
| 2 | 4 | 2 |
| 3 | 3 | 1 |
| 4 | 1 | 3 |
+----+----------+--------------+
ID is primary
event_id should be foreign key to events.id
applicant_id should be foreign key to users.id
I will be the first to admit that I am very new to this. I just learned how to use MySQL a few days ago. I can grab stuff from a single table, but I am unsure how to grab from multiple tables.
This is the SQL query I tried
SELECT DD_events.id, event_id, applicant_id, guild, level, class, DD_users.id
FROM DD_events, DD_event_apps, DD_users
WHERE DD_event_apps.event_id = DD_events.id
AND DD_event_apps.applicant_id = DD_users.id
and tried to print_r an array but the array turns up empty.
So a few questions pertain to this:
1: How would I count and display as a number how many people (users and randoms) are signed up for an event?
eg: event 3 should have 4 total (2 users and 2 randoms)
2: How do I see if a particular individual is signed for an event and display text based if they are or not?
eg: user 1 is signed up for event 3 so it would be "Registered" but user 2, who is not signed, would display "Not Registered"
3: I want to display info for who is signed for a particular event in 2 tables, 1 for users and another for randoms.
eg: Event 3 would have 2 users info (username, guild, class, level) under the users table and then 2 random users info (name, class, level, what user applied this person) in the random table.
Any and all help is appreciated even if you can answer 1 part.
I'm thinking this would be your base query:
SELECT
event.id,
app.applicant_id,
usr.guild,
usr.level,
usr.class,
usr.id AS Userid
FROM
DD_events event
JOIN
DD_event_apps app
ON (event.id = app.event_id)
LEFT JOIN
DD_users usr
ON (app.user_id = usr.id)
You can make modifications to this to aggregate it, like so:
SELECT
event.id,
COUNT(app.applicant_id) AS ApplicantCount,
COUNT(DISTINCT usr.guild) AS UniqueGuilds,
COUNT(DISTINCT usr.level) AS UniqueLevels,
COUNT(DISTINCT usr.class) AS UniqueClasses,
COUNT(DISTINCT usr.id) AS UniqueUsers
FROM
DD_events event
JOIN
DD_event_apps app
ON (event.id = app.event_id)
LEFT JOIN
DD_users usr
ON (app.user_id = usr.id)
GROUP BY
event.id
I could write those scripts for you, but I think this provides a good starting point for you to continue from. You'll find that T-SQL is fairly simple when you are trying to get the results you are looking for. Hope this helps!
<?php $query = "SELECT count(*) AS numbuh FROM DD_event_apps WHERE event_id = {$row['id']}";
try
{
// These two statements run the query against your database table.
$stmt = $db->prepare($query);
$stmt->execute();
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
echo($query);
// Finally, we can retrieve all of the found rows into an array using fetchAll
$count = $stmt->fetchAll();
echo($count['numbuh']); ?>

mysql group by table b, inner join table a for a random

here is my 2 tables, id for a inner join event. i want to do this thing:
in table b, there has 10 albums, i want random get out 4 albums. then each album select one record, the record is random position in the album.
so that i will get 4 records back (these 4 records with no duplicate id), then take these 4 records for a inner join query, to get the title from table a.
here just little records just for test. in the fact, i have 300,000 records in table a and 2,000,000 records in table b.
table a
+-----+-------+
| id | title |
+-----+-------+
| 1 | a1 |
+-----+-------+
| 2 | a2 |
+-----+-------+
| 3 | a3 |
+-----+-------+
| 4 | a4 |
+-----+-------+
| 5 | a5 |
+-----+-------+
| 6 | a6 |
+-----+-------+
table b
+-----+--------+
| id | album |
+-----+--------+
| 1 | album1 |
+-----+--------+
| 2 | album1 |
+-----+--------+
| 3 | album1 |
+-----+--------+
| 6 | album1 |
+-----+--------+
| 2 | album2 |
+-----+--------+
| 3 | album2 |
+-----+--------+
| 5 | album3 |
+-----+--------+
| 6 | album3 |
+-----+--------+
| 3 | album4 |
+-----+--------+
| 2 | album5 |
+-----+--------+
| 4 | album5 |
+-----+--------+
| 5 | album5 |
+-----+--------+
| 1 | album6 |
+-----+--------+
| 3 | album6 |
+-----+--------+
| 2 | album7 |
+-----+--------+
| 4 | album7 |
+-----+--------+
| 1 | album8 |
+-----+--------+
| 5 | album8 |
+-----+--------+
| 3 | album9 |
+-----+--------+
| 2 | album10|
+-----+--------+
| 5 | album10|
+-----+--------+
I am not good at mysql query. In my mind I would do
select * from b group by album order by random() limit 0,4
get back 4 album, then do a inner join query (this query not correct, how to check the b.id no duplicate?)
select * from b inner join a on b.id = a.id where (select id from b where b.album = '".$row['album']."' order by random() limit 1)
I need an easy and quicker method, the best is just use one query. many thanks.
AFAIR, "ORDER BY RAND()" is extremely slow solutions, especially on tables like you have (2 million+ records), so I'd recommend looking at something similar to these kind of articles first: http://www.greggdev.com/web/articles.php?id=6
So, you should know the number of records in your table before running the query and then do something like:
"SELECT * FROM `album` LIMIT 1 OFFSET " . rand(0,$count)
This will return you 1 random row a bit more efficiently, I believe.
Also, I think it's not a good idea to store album references as string in tracks table, you'd rather use a proper integer foreign key album_id referenced to albums.id. Then you can join both tables much fatser. If I were you, I'd do first:
ALTER TABLE `tracks` add column `album_id` int;
UPDATE `tracks` SET `album_id` = SUBSTRING(`album`,5);
Then, after doing this and combining with the solution above, launch something like:
"SELECT * FROM `album` INNER JOIN `tracks`ON `tracks`.`album_id` = `albums`.`id` LIMIT 1 OFFSET " . rand(0,$count)
Since I'm neither an expert on MySQL nor on PHP, I'll try with pseudocode and generic SQL. I have renamed your tables to albums and tracks for sake of readability.
First fetch the four random records to your PHP application:
select id from albums order by random() limit 4
Second, iterate over the resulting result set of four IDs and fetch the corresponding tracks (pseudo-php):
foreach($album_ids as $id):
execute_query("select id from tracks where album_id = ? order by random(), limit 1", $id)
It is not obvious to me how you match your tracks to their albums. You should have something like tracks.album_id as a foreign key to albums.id, that's how I designed my queries. You should adapt as appropriate, the underlying logic behind my solution should remain the same.

Categories