How to retrieve tables from database tables based on 1s and 0s? - php

I have 2 tables at the moment: Artists and Genres.
Genres are connected to artists using artist_id. The phpmyadmin genres table is set up as follows:
1s indicates that the artist with id=3, has selected classical and rap using a checkbox.
I would like to efficiently display a card, which will display the artist genres in a list. For every 1 in the row where artist_id = $id , output all genres ( in our case, classical and rap).
I was thinking about creating a new object called artistgenre, and using new artistgenre(); to create a new object and assign attributes. Maybe I don't even need to do that. Currently I have an object called artist, and I create $artist = Artist::findbyid($sessionid); and use $artist->name; $artist->location; to output data from the database.

I think this query is what you need:
SELECT g.id, g.name
FROM artists a
INNER JOIN artist_genres ag ON a.id = ag.artist_id
INNER JOIN genres g ON ag.genre_id = g.id

Related

Query result from database

I have two tables : galleries and shared galleries.
Structure of galleries: (for storing images of individual students. One student contains multiple images)
id, student_id, classroom_id, image
Structure of shared_galleries: (for storing images which are common to all students in a classroom. One classroom contains many images):
id,classroom_id,image
Other than these two tables I have students table and classrooms table. Students table store the classroom_id.
I need to get a query so that I can display the images stored in 'galleries' for a student and those stored in shared gallery of the classroom in which that student belongs in a single page. How can I achieve this ? Something like this returns duplicated results :
select galleries.id as gid,
shared_galleries.id as sid,
galleries.student_id, galleries.classroom_id
from galleries
inner join shared_galleries on galleries.classroom_id=shared_galleries.classroom_id
where galleries.student_id=31 and galleries.classroom_id=28
You will need to join the student to the shared_galleries along the relations to get the right results
SELECT
g.image AS image,
0 AS is_shared
WHERE
g.student_id = :student_id
FROM
galleries AS g
UNION
SELECT
sg.image AS image,
1 AS is_shared
FROM
shared_galleries AS sg
LEFT JOIN classrooms AS c ON c.id = sg.classroom_id
LEFT JOIN students AS s ON s.classroom_id = c.id
WHERE
s.id = :student_id
This should give you all the images for a student with :student_id,
I've also added the is_shared column in case you need to know the origin of the image
Since your images are stored on a per-record basis (in both galleries and shared galleries, using a JOIN is not needed. Use a UNION instead:
SELECT
galleries.id AS ID,
galleries.student_ID AS StudentID,
galleries.classroom_id as ClassroomID,
galleries.image as Image
WHERE
galleries.student_id = 31
UNION
SELECT
shared_galleries.id AS ID,
NULL AS StudentID,
shared_galleries.classroom_id as ClassroomID,
shared_galleries.image as Image
WHERE
shared_galleries.classroom_ID = 31
This will produce a list of records, with each record containing one image (since the number of images per student and the number if images per classroom is never consistent)
If you want do a little extra and ensure that your classroom images are always linked to the correct student, then declare a variable at the beginning to set the student_id value, and then use it in the second SELECT statement.

Select items where ID present in another column MySQL

I have a table of albums, each album has an ID.
I also have a table of reviews, each review is linked to a corresponding album through the column albumID.
I'm wondering how I can select all albums who's ID's are present in the reviews table.
I was thinking of selecting all albumId's from the reviews column then doing a select where id in but I feel like this would be horribly inefficient.
This is in MySQL
Albums Table
- ID
Reviews Table
- ID
- albumID
Desired result: All albums who have a review. (eg: All albums that have their ID present in the Reviews table)
Here's one approach using a simple JOIN. The inner join notation will only include records that exist in both tables. It allows you to access data in both tables which may be useful if you need data out of reviews too.
Select * from albums A
inner join reviews R
on A.ID = R.AlbumID
This next approach is generally the fastest but you can only get data from albums. This uses what's known as a correlated sub query and is generally the fastest approach.
SELECT * from albums A
where exists (Select 1 from reviews R where A.ID = R.albumID)
and a third approach but generally the slowest... uses a concept called IN(). The sub query here generates a list of ID's from reviews and only shows albums in that list.
Select * from albums where ID IN (SELECT albumID from Reviews)
This would work:
select a.* from albums as a
inner join reviews as r
on r.albumID = a.ID

Joins and Many to Many Relationship in mySQL

So I have a database consisting of posts and categories using the following tables
posts (PostID, PostName, PostCategory)
categories (CategoryID, CategoryName)
then I have another table which is there to join the two together as follows
posts_categories (Posts_Category_ID, PostID, CategoryID)
I would like to know how to create an SQL Query for the following commands:
a. Create an SQL Query to populate a single POST with MULTIPLE CATEGORIES
b. Search for all POSTS that CONTAINS MULTIPLE CATEGORIES
ex a. Create Post Named "Post1" with Categories "Digital","Analog","Linear"
ex b. Search for all Posts containing Categories "Digital" and "Linear"
Thanks a lot for your help.
If you are talking about fetching the data then do a join between the tables using the chaining table. Something like below
select p.PostName, c.CategoryName
from posts p inner join post_categories pc on p.PostID = pc.PostID
inner join categories c on c.CategoryID = pc.CategoryID
where c.CategoryName in ('Digitl','Linear')
I don't know if I totally get your question, but the query below should return those entries in the many-to-many table that have more than one categoryId for a single postId. Let me know if this helps:
select *
from posts_categories pc
join (
select postId
from posts_categories
group by postId
having count(categoryId) >1
) x on x.postId = pc.postId
Also, you should have a unique constraint on this table for the postId and categoryId columns or make that your primary key.

retrieve data from 4 tables

I have these four table assume that ring table consist of five fields(jewelry_id,ring_id,image,type,brand_id)
Note that brand table have its foreign key in ring table and ring and style both have foreign keys in ring_style table. now i want to retrieve the following data from these four table
(ring_id, image,type, brand,style) but did't get the query any help will be greatly appreciated.
You just join each table using the columns that relate them.
SELECT
ring.ring_id,
style.image,
ring.type,
brand.brand,
style.style
FROM
brand
INNER JOIN
ring
ON
brand.brand_id = ring.brand_id
INNER JOIN
ring_style
ON
ring.jewelry_id = ring_style.jewelry_id
INNER JOIN
style
ON
ring_style.style_id = style.style_id
SELECT
ring_id, image, type,
brand,
style
FROM ring
LEFT JOIN brand ON ring.brand_id = brand.brand_id
LEFT JOIN ring_style ON ring.jewelry_id = ring_style.jewelry_id
LEFT JOIN style ON ring_style.style_id = style.style_id
Note that each ring will appear one or more times. It will appear more than one time when there is more than one ring_style record for the ring.
You have to use the SQL command JOIN:
An example to get the information from ring and brand with one query use:
SELECT * FROM ring
JOIN brand ON ring.brand_id = brand.brand_id;
WHERE ring.jewelry_id = 123456
Use multiple JOIN in one query to get multiple tables connected in one query.

Join SQL tables

Suppose that in table "ab" I have the names of the students that get along from class "a" and class "b", identically I have table "ac" and "bc". What SQL query should I use in order to get all the combinations possible of students who can form groups (i.e. "get along together")? And how can i extend this to n classes?
For example: John from class a gets along with Jen from class b and Steff from class c, and Jen and Steff get along. Therefore John, Jen and Steff can form a group).
For this I would create two tables, a student table (id, name, class) and a relationship table (student1, student2). You might also want to add a class table for the time, location etc of the class.
A friendship would have two relationships (2,3) and (3,2) to describe it as two way. One way might be a follower or fan of another student.
This will scale up to a lot more than 3 classes.
Then you can use multiple joins to get friends of friends and so on to an arbitrary depth.
Here is a query to get friends of friends (fof):
SELECT fof_details.*
FROM relationships r
INNER JOIN relationships fof
ON r.student2 = fof.student1
INNER JOIN student fof_details
ON fof_details.id = fof.student2
WHERE r.student1 = '12';
There are also database engines made specifically for doing graph modeling like this.
http://openquery.com/blog/graph-engine-mkii
This query should return all students who can be in one group with John.
WITH ABC AS (SELECT AB.A, AB.B, AC.C FROM (SELECT * FROM AB
INNER JOIN BC
ON AB.B=BC.B)
INNER JOIN AC
ON (AC.C=BC.C AND AB.A=AC.A))
SELECT STUDENT FROM (
SELECT AB.B STUDENT FROM ABC WHERE AB.A='John'
UNION
SELECT AC.C STUDENT FROM ABC WHERE AB.A='John')
GROUP BY STUDENT
PS.: Written fast without any syntax check, hope you'll be able to bring this to work :)
The initial query can be satisfied by the code
select ab.a, ab.b, ac.c
from
ab inner join
bc on ab.b = bc.b inner join
ac on ac.a = ab.a and bc.c = ac.c
Stepping up to n classes will get progressively more complex as n=4 would be the same query with the additional three joins
inner join ad on ab.a = ad.a
inner join bd on bd.b = ab.b and ad.d = bd.d
inner join cd on cd.c = ac.c and ad.d = cd.d
2 classes requires 1 table and no joins,
3 classes requires 3 tables and 2 joins,
4 classes requires 6 tables and 5 joins
So we can see it getting progressively more complex as we proceed
First you don't want to have a table for each class. You are capturing the same type of information in multiple tables and this is generally considered a bad practice. You want to "normalize" your data so that the same data exists in one place.
Second, name your tables appropriately so that you understand what you are actually trying to build. Maybe you are generalizing to mask what your intentions for the actual implementations are by using "ab" in the question, but if you are doing this in your actual code it will hurt you in the long run.
It appears you need a people table with names and a friends table where you track who is friends with who:
create table people ( id int, name char(128) );
create table friends ( id int, person_id int, friend_id int );
Then you just need to have the query to get the groups:
SELECT person.* FROM friends
INNER JOIN friends grp
ON friends.friend_id = grp.person_id
INNER JOIN people person
ON person.id = grp.friend_id
WHERE friends.person_id = 42;

Categories