Finding value in a comma-separated text field in MySQL? - php

I've got a database of games with a genre field that has unique ids in it that are separated by commas. It's a text field. For example: HALO 2 - cat_genre => '1,2' (Action,Sci-Fi)
I'm trying to make a function that calculates the total number of games in that genre. So it's matching 1 value to multiple values separated by commas in the db.
I was using SELECT * FROM gh_game WHERE cat_genre IN (1) which would find Action Games.
I'm trying to work this out, I thought I had nailed it once before but I just can't figure it out.

You need to create a many to many relation. like so
CREATE TABLE gameGenreTable ( id int NOT NULL PRIMARY KEY, genreID, gameID)
EDIT: if you're using InnoDB you can also create foreign keys on genreID and gameID..
I would add a UNIQUE key on genreID, gameID
then you can do a query like this
SELECT genreID,count(genreID) as count from gameGenreTable GROUP BY genreID;
-- and join in your other table to get the genre name (or just use the ID).

Related

How to find a way that items with the same names wont collide with each other when left join tables

I have been looking around for answers for countless hrs and could not find much.I am making a food project and I was wondering if there is a way to prevent 2 items with the same name from colliding each other with their 2nd table.To make things clear I have 1 table which is
CREATE TABLE cuisine (id int,dish_name varchar(32));
//2nd table CREATE TABLE ingrediant (id int,dish_name varchar(32),ingrediant);
I was wondering if lets say 2 people posted dish_name = pizza with different ingrediants,when i left join how would the tables know which one to join because the only thing that are matching is the dish_name.
I know i could add the ingrediants to the first table but lets say i am adding up to 50 ingrediants and other items it is too much stuff.
An example i can use is Ebay.
If 2 people post items with the exact same name,when the item is clicked how does it know which info it is for.Hope it is clear
If you would model your relations correctly, you don't have that problem.
You would have to define a foreign key in the 2nd table, and the foreign key would have to refer to the primary key (or at least some other uniquely indexed field or combination of fields) in the 1st table. If you plan on using dish_name as a foreign key in the 2nd table, that would necessarily mean that dish_name would have to be unique in the 1st table.
This is probably a bad idea, so it's better to create a dish_id foreign key column in your 2nd table and get rid of the dish_name column.

Relating MySQL-table content correctly

I have the following tables in a database:
products
assembly_steps
parts
warnings
I want to relate the content of these tables as follows:
A product consists of many assembly_steps. An assembly_step can have different part and warnings. So I build the tables
assembly_steps_has_parts
assembly_steps_has_warnings
products_has_assembly_steps
to relate the data. The ...has...-tables are connected with their related partners by foreign keys. I modeled that with the MySQL-Workbench.
I am confused about the mechanism to relate the info. How do I program that in PHP?
I think first you add the content on the lowest level, that would be parts and warnings. Then you add the assembly step and relate the data. But I don't know how to do this.
Here you find an overview: Database-Model
Relational databases relate entities/values by recording them together in a row in a table.
To relate assembly_steps to parts, just insert a row into assembly_steps_has_parts, e.g. if you have the assembly_step_id in $assembly_step_id, and the part_id in $part_id, then:
INSERT INTO assembly_steps_has_parts (assembly_steps_id, parts_id)
VALUES ($assembly_step_id, $part_id)
You wouldn't program this in PHP, you'd handle it fully with mysql. The way this would be structured in mysql would be something like this:
assembly_steps
assembly_id
assembly_description (or something like that
assembly_id is the primary key
parts
part_id
part_name
part_id is the primary key
assembly_steps_has_parts
assemply_id
part_id
In this table, you'd have a dual primary key. Both assembly and part id are foreign keys AND primary keys for their respective tables.
The way that dual primary keys work is that there are two keys to make up one primary key on one table. That means that instead of limiting to 1 key, it limits the table to one of any combination of these keys to make one.
For instance:
pk1 pk2
1 1
1 2
1 3
2 1
2 2
2 3
You could query them like this (this is a generic query, but the basic idea)
select a.assembly_description, p. part_name
from assembly_id a
join assembly_steps_has_parts ats
on a.assembly_id = ats.assembly_id
join parts p
on ats.part_id = p.part_id
You'd do the same thing for the other tables. From that point you'd just call the results of your query in php the way you would handle any other query.

How to retrieve count values as multiple columns using group by in single query in MySQL?

I am writing a complex MySQL query. My actual query is more complex than I mentioned below.
I have a table named example and columns are id, name, option_1, option_2 . Of course id column is PK . I want to retrieve like this:
SELECT `id`,`name`,count(`option_1`),count(`option_2`)
My problem is I want to use "GROUP BY `id`" for count(`option_1`) and "GROUP BY `name`" for count(`option_2`) respectively. Now I have to break down it into multiple code in my php code.
How can I achieve what I want in a single query?
What you're asking for doesn't make a ton of sense. You want option 1 grouped by id and option 2 grouped by name, and you want to show all four columns in one result set.
First of all, if id is a primary key, then the count will just be the number of rows in the table since there will be no duplicate ids.
Second, even if id wasn't a primary key, and there were duplicate values, the grouping is different, so the counts represented in your result set would be grouped incorrectly.
Given that id is a primary key, perhaps your intention is actually to get a total count of the rows in the table. Perhaps this query would suit your needs?
SELECT
name,
COUNT(option_2) AS options
FROM
example
GROUP BY
name
UNION ALL
SELECT
'Total' AS name,
COUNT(*) AS options
FROM
example
This should get you a count of all the option_2 values, grouped by name, with the final row having a name of 'Total' and the count being the total number of rows in the table.
Aside from that, I'm not sure you're going to find the answer you're looking for due to the problems you would encounter matching up groupings.

Storing an random size array in a mySQL column

I have a table. It cointains two columns unique song and genre. Unique song stores a string, doesn't really matter what.
Genres contains an array of strings (genres that apply to the song), number of elements in the strings being random (to big to ditch the array and just make additional columns).
I know that this setup does not work in mySQL as I set it up, but that is what I need.
One way to do it would be serialization, but I would very much like to be able to query out all rock songs without having to first querying them all, unserializing and then finding my match.
Since all of the array contents are of the same type, is there a column that would support such an input? (int is a limited array of ints in a way, no?)
You've got a many-to-many relationship - one song can have multiple genres, and a genre can be used by multiple songs.
Create a table called Song, that contains information about the song and some unique identifier. For the sake of argument, we'll just say it's the name of the song: s_name.
Create a table called Genre, that contains information about genres. Maybe you have the genre, and some information on what style of music it is.
Finally, create a table called SongAndGenre, that'll act as a bridge table. It'll have two column - a song ID (in our case, s_name), and a genre ID (say, g_name). If a song S has multiple genres G1 and G2, you'll have two rows for that song - (S, G1) and (S, G2).
You now have a table, let's say, songs, containing a column genres.
To know the genres of song #123, you can now issue
SELECT genres FROM songs WHERE id = 123;
What you need to do is to create two additional tables:
CREATE TABLE genres (
genre_id integer not null primary key auto_increment,
genre_name varchar(75)
);
CREATE TABLE song_has_genre (
song_id integer not null,
genre_id integer not null
);
To store the fact that song 123 is in genres 'Folk', 'Pop', 'Jazz' and 'Whatever', you can run:
INSERT INTO song_has_genre
SELECT 123, genre_id FROM genres
WHERE genre_name IN ( 'Folk', 'Pop', 'Jazz', ... );
To query what songs are in genre Folk,
SELECT songs.*, genres.genre_name FROM songs
JOIN song_has_genre AS shg ON ( songs.id = shg.song_id )
JOIN genres ON (shg.genre_id = genres.genre_id)
WHERE genres.genre_name = 'Folk';
A bit more work is needed to avoid duplicates if you select two genres and one song is in both, or to retrieve all genres of some songs selected based on genre (i.e., you search 'Pop', and want to find 'Pop,Jazz,Folk', 'Pop,Techno', 'Pop', 'Pop,Whatever', but not 'Techno,Jazz,Folk,Anything except Pop'), but it's doable (e.g. using GROUP_CONCAT and/or GROUP BY, or in the code outside MySQL).

MySQL - Searching in a multiple value field

In my database table I have the following fields:
Table Supplier:
id
name
vehicles
A supplier can have multiple vehicles. The field 'vehicles' will store multiple values. At the moment I am delimiting the values on a 'pipe' symbol, although this can be changed to a comma if need be.
On my front-end form I have a checkbox list - a user can select multiple vehicles. The back end script needs to do a search and bring back all suppliers that contain any of the specified vehicle id's.
So in other words we are searching with multiple values in a multiple value field.
The checkbox list name is vehicle_type[] and will end up in the $_POST array as (for example):
Array
(
[0] => 1
[1] => 4
[2] => 6
)
Is this possible to do? I could obviously do this using a join table but ideally I would like to do it this way. I am using PHP as my scripting language if that helps.
The field 'vehicles' will store multiple values. At the moment I am delimiting the values on a 'pipe' symbol, although this can be changed to a comma if need be.
Please don't do that. Storing delimited data in a text field is no better than storing it in a flat file. The data becomes unqueryable.
You want a nice, happy, normalized database.
CREATE TABLE Suppliers (
supplier_id INTEGER PRIMARY KEY,
...
);
CREATE TABLE Vehicles (
vehicle_id INTEGER PRIMARY KEY,
...
);
CREATE TABLE Supplier_Vehicles (
supplier_id INTEGER NOT NULL REFERENCES Suppliers(supplier_id),
vehicle_id INTEGER NOT NULL REFERENCES Vehicles(vehicle_id),
UNIQUE KEY(supplier_id, vehicle_id)
);
-- Grab all the Vehicles for Supplier 39
SELECT Vehicles.*
FROM Vehicles, Supplier_Vehicles
WHERE Supplier_Vehicles.supplier_id = 39
AND Supplier_Vehicles.vehicle_id = Vehicles.vehicle_id
The checkbox list name is vehicle_type[] and will end up in the $_POST array as (for example) [...] Is this possible to do?
It's very possible, and is a good idea. Try it and find out how well it works.

Categories