How to merge two tables in a mysql query - mysql

First of sorry I know mysql is not recommended any more but in this case I have no control and have to use it.
Now onto the question.
I have two tables
Games and videos
Inside games I have
| id | gameID | GameTitle |
| 1 | 1 | Halo ODST |
| 2 | 2 | Disgaea 4 |
Inside videos I have
| id | game | videoTitle | image |
| 1 | 1 | Title 1 | PATH |
| 2 | 1 | Title 2 | PATH |
| 3 | 2 | Title 3 | PATH |
| 4 | 1 | Title 4 | PATH |
I need to basically do the following
Select x,y,z from video where videos.game = games.gameID
which will basically read
select id, videoTitle, image from videos where video.game = 1
(or some other numeric value)
I’m aware I have to use a join however nothing I have tried appears to be working and yeah I’m getting nowhere with this.
The closest I am is the below query which says it works but is returning an empty result set so clearly its wrong somewhere.
SELECT * FROM `games` INNER JOIN `videos` on `game` WHERE `game` = 1
If its any help I'm using phpmyadmins sql query tool rather than actual code at this stage as i just want to get it working before coding it.
Any help is greatly appreciated.
Thanks.

SELECT *
FROM `games` g
INNER JOIN
`videos` v
ON v.game = g.gameId
WHERE g.gameId = 1

you can use view to merge table and can perform operations on that..
create view view_name as
select Games.id,gameID, GameTitle,videos.id, game, videoTitle, image
from Games,videos
where videos.game = games.gameID
where section will contain ids or anything you want to match

Related

How to fill a SQL column with data (calculated) from another table

I have a question and don't know how to approach the problem exactly.
I have two tables as following:
Clients
| c_id | name | reference |
| ---- | ------- | --------- |
| 1 | ClientA | 1 |
| 2 | ClientB | 1 |
| 3 | ClientC | 2 |
| 4 | ClientD | 2 |
| 5 | ClientE | 1 |
| 1 | ClientF | 3 |
Tour
| t_id | name | count |
| ---- | ------- | ----- |
| 1 | TourA | 3 |
| 2 | TourB | 2 |
| 3 | TourC | 1 |
"Reference" in the "Client" table is defined as foreign key.
Is it possible to fill the column "count" in the table "Tour" with an automated formula where it counts how many times the t_id appears in the "Client" table?
Something like: COUNT(c_id) FROM clients WHERE reference = t_id
I have read about to create a view but not sure how to fetch the data correctly.
Thanks for your help,
Raphael
UPDATE #1:
The workflow as described with the view works perfectly. I'm trying now to fill the column via a trigger but I'm getting an SQL error with the following code:
CREATE TRIGGER client_count
AFTER UPDATE
ON clients FOR EACH ROW
SELECT t.*,
(
SELECT COUNT(*) FROM clients c where c.tour_id = t.tour_id
) AS tours.tour_bookedspace
FROM tours t
The view you have referred to is indeed the way to go here. The view you need to create needs to join the two tables and perform a count aggregation as follows:
CREATE VIEW vwTour
AS
SELECT t.t_id,
t.name,
COUNT(t.name) AS Cnt
FROM tour t
JOIN Clients c
ON t.t_id = c.reference
GROUP BY t_id,
t.name
No you can't. Generated columns can only use data from the same table.
The options you have are:
1. Use a view
You can select from a view that computes the extra value(s) you want. For example:
create view tour_data as
select t.*,
(
select count(*) from clients c where c.reference = t.t_id
) as number_of_clients
from your t
2. Use a trigger
Alternatively, you can add the extra column number_of_clients and populate it using a trigger every time a row is added, modified, or deleted from the table clients.

Separating a comma separated string to a new table

I inherited a project that has comma separated strings stored in a field called 'subsector' in a table named 'com_barchan_project'. I need to change this horrible design, since it's proving to be an issue trying to parse through this field. See HERE for the full story:
| id | name | sector | subsector |
+----+------+--------+-----------+
| 1 | test | 2 | 3,4,7 |
+----+------+--------+-----------+
| 2 | door | 5 | 2 |
I have created a new table called 'com_barchan_project_subsector_join' with the required fields and would like to move the values stored in 'com_barchan_project' to this new empty table.
Can anyone help me with the SQL statement that would accomplish this?
Here's what the new 'com_barchan_project_subsector_join' table should look like:
| id | project_id | subsector_id |
+----+------------+--------------+
| 1 | 1 | 3 |
+----+------------+--------------+
| 2 | 1 | 4 |
+----+------------+--------------+
| 3 | 1 | 7 |
+----+------------+--------------+
| 4 | 2 | 2 |
Once I move over the data, I will remove the 'subsector' field from the 'com_barchan_project' table and be done with it.
Thanks for your help!!!
John
Using shorter table names for brevity/clarity; and assuming you have (or can easily make) a comprehensive subsectors table...and assuming your csv are stored in a consistent format (no spaces at least).
INSERT INTO `project_subsectors` (project_id, subsector_id)
SELECT p.id, s.id
FROM projects AS p
INNER JOIN subsectors AS s ON p.subsector = s.id
OR p.subsector LIKE CONCAT(s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id)
;
I can't guarantee it will be fast; I'd be surprised if it was.
ON FIND_IN_SET(s.id, p.subsector) > 0 may work as well, but I am not as familiar with the behavior of that function.

Mysql: how to return value or empty string from column ids in table (multi table)

I'M trying to extract all information into my table, but I need to change id, when available, to the name into another table.
I have 1 table like that:
|------------------------------|
|-id-|-systems-|-remote-|-deco-|
| 1 | NULL | 3 | |
| 2 | 21 | NULL | 2 |
|-------------------------------
each column like "systems" / "remote" / "deco" refer to an id into another table
I know how to use INNER JOIN. But if I use that, I got an empty result because the value need to be appears into the others tables.
ex.:
SELECT qd.id,s.name as systems,r.name as remote, d.name as deco
FROM `quote_data` qd
INNER JOIN systems s ON qd.systems=s.id
INNER JOIN remote r ON qd.remote=r.id
INNER JOIN deco d ON qd.deco=d.id
I got empty result.
In the best words, I need to do something like:
|------------------------------|
|-id-|-systems-|-remote-|-deco-|
| 1 | | R42 | |
| 2 | GTV | | B21 |
|-------------------------------
Also, I use innoDB table
Any Idea how to fix that?

mysql query - conditional statements?

Here are my tables:
files
+----+--------+
| id | name |
+----+--------+
| 2 | file_1 |
| 3 | file_2 |
| 5 | file_3 |
+----+--------+
files_already_viewed
+----+---------+----------+------+
| id | file_id | category | user |
+----+---------+----------+------+
| 1 | 3 | 5 | 1 |
| 2 | 2 | 1 | 1 |
| 3 | 5 | 1 | 1 |
+----+---------+----------+------+
categories_files_join
+--------+---------+
| cat_id | file_id |
+--------+---------+
| 1 | 2 |
| 1 | 5 |
| 5 | 3 |
| 1 | 3 |
+--------+---------+
file_2 (which has an id of 3) has two categories associated with it, cat_id 5 and cat_id 1.
It has been viewed once by a user searching for files under the category 5.
But now the user is searching for files under the category 1.
I need a query that won't show file_2 under the "1" category until all the other files with a category id of 1 have been viewed first, since the user already viewed file_2. Basically putting file_2 at the end of the list.
Here is my query so far:
SELECT name FROM files
WHERE files.id NOT IN (
SELECT file_id FROM files_already_viewed
WHERE user='1')
ORDER BY most_viewed DESC
LIMIT 1
I order my search by the most popular viewed file. But i don't want to show files that have already been viewed regardless of category until all other files have been viewed with in that specific category.
Any help would be greatly appreciated. thanks!
Actually, your query will not show files already shown. What you want to do is to order those already shown files at the bottom. So, basically you'll have to sets of data: first, the data that matches the needed criteria and that the user has not been shown yet and then the data that matches the needed criteria but the user has been shown.
The way I'm handling the sets is by adding a customSort id for each set and then ordering by it. Now the short explanation is that the first group I get it by faking a MINUS operation with a left join: I get all the files that have not yet been seen. Then, the second group is a bit easier as it just needs to get all the files that have already been seen. So, the UNION of both sets in the customSort order would be the result you're looking for so now you just need to filter that result by the current query criteria (category = 1 in this case).
select file_id from (
select distinct cf1.cat_id, cf1.file_id, 1 as customSort
from CategoriesFiles1 cf1
left join FilesViewed1 fv1 on (fv1.file_id = cf1.file_id)
where (fv1.file_id is null)
union
select distinct cf2.cat_id, cf2.file_id, 2 as customSort
from CategoriesFiles2 cf2
join FilesViewed2 fv2 on (fv2.file_id = cf2.file_id)
) FinalResult
where (FinalResult.cat_id = 1)
order by customSort
Here is a link with the example. You can comment each data insert in files_already_viewed to see how, after viewing a file, the result changes. Besides, changing select file_id from to select * from will allow you to clearly see which set each row belongs to.
Let me know if this works.

Joining from another table multiple times in a MySQL query

I am trying to do multiple joins on the same MySQL table, but am not getting the results that I expect to get. Hopefully someone can point out my mistake(s).
Table 1 - cpe Table
|id | name
|----------
| 1 | cat
| 2 | dog
| 3 | mouse
| 4 | snake
-----------
Table 2 - AutoSelect
|id | name | cpe1_id | cpe2_id | cpe3_id |
|-----------------------------------------------
| 1 | user1 | 1 | 3 | 4 |
| 2 | user2 | 3 | 1 | 2 |
| 3 | user3 | 3 | 3 | 2 |
| 4 | user4 | 4 | 2 | 1 |
------------------------------------------------
I would like to see an output of
user1 | cat | mouse | snake |
user2 | mouse | snake | dog |
..etc
Here is what I have tried
SELECT * FROM AutoSelect
LEFT JOIN cpe ON
( cpe.id = AutoSelect.cpe1_id ) AND
( cpe.id = AutoSelect.cpe2_id ) AND
( cpe.id = AutoSelect.cpe3_id )
I get blank results. I thought i knew how to do these joins, but apparently when I'm trying to match cpe?_id with the name of the cpe table.
Thanks in advance for any assistance.
You need left join 3 times as well. Currently your query only joins 1 time with 3 critieria as to the join. This should do:
SELECT a.name, cpe1.name, cpe2.name, cpe3.name FROM AutoSelect as a
LEFT JOIN cpe as cpe1 ON ( cpe1.id = a.cpe1_id )
LEFT JOIN cpe as cpe2 ON ( cpe2.id = a.cpe2_id )
LEFT JOIN cpe as cpe3 ON ( cpe3.id = a.cpe3_id )
And you probably mean to INNER JOIN rather than LEFT JOIN unless NULL values are allowed in your AutoSelect table.
I think your design is wrong.
With tables like that, you get it the way it's meant to be in relational databases :
table 1 : animal
id name
1 cat
2 dog
3 mouse
4 snake
table 2 : user
|id | name |
|--------------
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
table 3 : association
|id_user | id_animal|
|--------------------
| 1 | 1 |
| 1 | 3 |
| 1 | 4 |
| 2 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 3 |
| 3 | 2
| 4 | 4 |
| 4 | 2 |
| 4 | 1 |
---------------------
Then :
select u.name, a.name from user u, animal a, association ass where ass.user_id = u.id and ass.animal_id = a.id;
In this case, your solution won't produce a good dynamic database. There are other ways to make combinations of multiple tables. I can show you by my own database what you should use and when you should use this solution. The scheme is in dutch, but you'll probably understand the keywords.
Like you, I had to combine my windmills with a kWh-meter, which has to measure the energyproduction of my windmills. What you should do, is this case, is making another table(in my case molenkWhlink). Make sure your tables are INNODB-types(for making Foreign keys). What I've done is combining my meters and mills by putting a pointer(a foreign key) of their ID(in Dutch Volgnummer) in the new table. An advantage you may not need, but I certainly did, is the fact I was able to extend the extra table with connection and disconnection info like Timestamps and metervalues when linking or unlinking. This makes your database way more dynamic.
In my case, I Also had a table for meassurements(metingoverzicht). As you can see in the scheme, I've got 2 lines going from Metingoverzicht to molenkwhlink. The reason for this is quite simple. All meassurements I take, will be saved in table Metingoverzicht. Daily meassurements(which are scheduled) will have a special boolean put on, but unscheduled meassurements, will also me saved here, with the bollean turned off. When switching meters, I need the endvalue from the leaving meter and the startvalue from the new meter, to calculate the value of todays eneryproduction. This is where your solution comes in and an extra table won't work. Usually, when you need just one value from another table a JOIN will be used. The problem in this case is, I've got 2 meassurementIDs in 1 link(1 for connecting and 1 for disconnecting). They both point to the same tablecolumn, because they both need to hold the same type of information. That is when you can use a double JOIN from one table towards the other. Because, both values will only be used once, and just needed to be saved in a different place to avoid having 1 action stored on different locations, which should always be avoided.
http://s1101.photobucket.com/user/Manuel_Barcelona/media/schemedatabase.jpg.html