How to call back a parents name from child table? - php

I have two tables as follows:
games
id | game_name | console_id
1 God of War 1
2 Zelda 3
3 Sonic 4
consoles
id | console_name
1 PS4
2 Xbox
3 Switch
4 Mega Drive
I've linked them via the Designer view so when I go to insert a name game (I'm doing this via the phpMyAdmin control panel) as soon as I click on "console_id" it gives me a drop down of 1 - PS4, 2 - Xbox and so on. So the games table can now read from consoles table no problem so I think I've got everything correct from that side of things.
Now I can run this code
SELECT id, game_name, console_id FROM games
and I will get the output
1 - God of war - 1
What I would like to do is something like this:
SELECT id, game_name, console_id.console_name FROM games
So instead of it saying God of war is on console ID 1, it says its on console.name PS4.
How can I do it, as I thought by linking the tables it would allow me to do it.

You need a JOIN between the tables. In this case, you want to join the consoles table to the games table by matching the id field of the former to the console_id field of the latter, like this:
SELECT g.id, g.game_name, c.console_name
FROM games g
INNER JOIN consoles c
ON c.id = g.console_id

Related

Get data from 3 tables by one query

I have a small blog project
I have 3 tables
Posts
PostID | TITLE | WRITERS(USERS) | CATEGORIES
1 | SOME TITLE | 1,2 | 1,2
USERS
USERID | USERNAME
1 | Alaa
2 | John
Categories
1 | Business
2 | Marketing
I am trying to get this output
POST TITLE: SOME TITLE
Writers: Alaa And John
Categories: Business, And marketing
Please note that i am talking about a very big loop, 100 post in a page for many viewers
So, currently i have two ideas
First idea
1- take value from writers ( 1,2 )
2- Explode it by php
3- use mysql query to bring the writers
4- Do the same thing for categories
Second idea is to remove the columns writers, categories from the posts table and create a fourth table and call it connections, which will refer ids to each others ( connect everything together )
But i don't even know if i can do the mysql query
You can get all these values in one MySQL query.
SELECT p.TITLE AS `Post Title`,
GROUP_CONCAT(DISTINCT u.USERNAME) AS Writers,
GROUP_CONCAT(DISTINCT c.CategoryName) AS Categories
FROM Posts p
JOIN Users u ON FIND_IN_SET(u.USERID, p.WRITERS)
JOIN Categories c ON FIND_IN_SET(c.Id, p.CATEGORIES)
GROUP BY p.TITLE
Output:
Post Title Writers Categories
SOME TITLE Alaa,John Business,Marketing
Demo on dbfiddle
Note: storing values in comma separated lists (e.g. your WRITERS and CATEGORIES columns) is a bad idea and makes writing this sort of query problematic (it's only MySQL's FIND_IN_SET function which makes it workable at all) and you should look into properly normalising your data (one value per row). Here is an example of how your database could look normalised.

Query to see how many times employees has worked same shifts

I run a management system where people who work different shifts are registered.
I'd like to be able to make a display of how many times each worker/volunteer worked same shifts, like this:
|Amy|Carl|Max|
|---|----|---|
Amy | X | 2 | 6 |
Carl| 2 | X | 5 |
Max | 6 | 5 | X |
I was hoping you had some ideas how to form the query.
The only idea I've come up with so far is to make PHP create a custom query for each user.
Select count(common between user 1 and 2), count(common between user 1 and ...)
Select count(common between user 2 and 1), count(common between user 2 and ...)
etc..
I consider this an ugly way to do it and I am hoping there is some way of retrieving this data within a single query.
The database is stored like this:
Shifts
ID
From
To
Working
ID
ShiftID
UserID
Users
ID
Name
You'll have to self-join the Working table:
SELECT a.UserID, b.UserID, count(a.ShiftID) AS common_shifts
FROM Working AS a
INNER JOIN Working AS b ON ((a.ShiftID = b.ShiftID) AND (a.UserID <> b.UserID))
HAVING common_shifts > 0
Couldn't you do a cross join where each row is compared to the other, and handle the case of userid=userid to put an X instead?

Facebook or LinkedIn like connection suggestion profile alert

I have a "users" table like this:
+-----+------------+---------+---------------+
| uid | first_name | surname | email |
+-----+------------+---------+---------------+
1 joe bloggs joe#test.com
2 bill bloggs bill#test.com
3 john bloggs john#test.com
4 karl bloggs karl#test.com
and a "connections" table like this:
+----+---------+----------+--------+
| id | user_id | user_id2 | status |
+----+---------+----------+--------+
1 1 3 1
2 3 1 1
3 4 3 1
4 3 4 1
5 2 3 1
6 3 2 1
Here id is auto auto_increment user id is saved in either user_id or user_id2. Status 1 means connection is approved and active.
Now I want to send an email alert to users with profile suggestion like Facebook or LinkedIn do. I assume it is possible to get mutual connections between users but not sure how to do. I have tried but it is not perfect. I want to get these all with one mysql query with user and their suggested connection profile. Any idea how to do this?
Many thanks in advance!
Such algorithms are never perfect: you can never know exactly if two people know each other. People might live in the same building, go to the same work, have 100 friends in common and even share the same hobbies without knowing each other (of course the odds are not that great).
What Social networks do exactly is of course unknown (that's part of the way they make money). But some aspects are known. For instance the number of mutual friends are important (together with for instance location, interests, hobbies, education, work, surname,...).
Based on what you provide, one can more or less only use the number of mutual friends. This can be done using the following query:
SELECT a.user_id, b.user_id2, count(*) --Select the two ids and count the number of transitive relations
FROM connections as a, connections as b --Use the table twice (transitivity)
WHERE a.user_id2 = b.user_id -- Transitivity constraint
AND a.user_id < b.user_id2 -- Maintain strict ordening (can be dropped when checked)
AND a.status = 1 -- First relation must be confirmed.
AND b.status = 1 -- Second connection must be confirmed.
AND NOT EXISTS ( -- Not yet friends
SELECT *
FROM connections as c
WHERE c.user_id = a.user_id
AND c.user_id2 = b.user_id2
)
GROUP BY a.user_id, b.user_id2 -- Make sure we count them correctly.
As you can see here, the fiddle calculates that (1,2), (1,4) and (2,4) are not yet friends, and all have one mutual friend.
Once the number of mutual friends surpasses a certain threshold, one can propose friendship.
I would however advice you to make your table more compact: add a CHECK to the table such that user_id is always strictly less than user_id2 (CHECK(user_id < user_id2)). This makes the database more compact, for most implementations of a database tool faster as well and queries will become simpler. What is after all the difference between (1,3,1) and (3,1,1).

Count how many times a value appears in sql query using php

I have created a database and website that will be used by football managers to select their team etc. Once a match has been completed events will be stored in the match_players table. Such events are Goal, Yellow Card, Red Card etc. I have no problem getting this information into php from SQL db.
I need to add up how many times a Goal appears (a '1' is placed in the SQL table) and for what team so that a final score can be displayed. So, for example, if Team A has 1 goal and Team B has 2 then I need to display that. I am trying to count the amount of times that a Goal is registered in the table. Any help will be greatly appreciated.
You can use MYSQL SUM
select SUM(Goal) from match_players where Team="A"
Or you can get the same for all teams by
select Team,SUM(Goal) from match_players group by Team
Why don't you demand this sum to SQL directly?
SELECT SUM(goals)
FROM match_table
WHERE team = 'Barcellona'
This should be much faster also than elaborate all data at "php-level"
If you want this detail for all teams
SELECT team,SUM(goals)
FROM match_table
GROUP BY team
Well if you store a 1 each time a goal is scored, your table looks like this:
TeamID goal
1 1
2 1
1 1
3 1
2 1
2 1
1 1
So you just want a count of how many times a team appears in that table:
select TeamID, count(*) from table group by TeamID
Will give you
TeamID | count(*)
1 | 3
2 | 3
3 | 1

MySQL server load optimization

Let's say we have 2 db tables.
First table "laptops"
id | name
1 apple
2 sony
...
and second table "colors"
id | color
1 white
2 black
2 red
2 blue
...
If I want to get some html table like
Laptop | Available colors
Apple 1 (white)
Sony 3 (red, blue, black)
...
I need to create "while" and query every time for every laptop. It will load server if there are more than 10 000 laptops for example. Is there any optimised way to get it work?
What you are looking for is a SQL JOIN. However you need to have a table which links both tables together.
Something like
SELECT * FROM laptops t
LEFT JOIN colors c ON t.id=c.id
e.g. if you want to Count colors you could do something like this:
SELECT t.id, t.name, COUNT(c.id) AS numberofcolors FROM laptops t
LEFT JOIN colors c ON t.id=c.id
GROUP BY t.id
If you also need to output color names you have to use GROUP_CONCAT

Categories