Query on multiple tables? - mysql

I need to create a single query that reads from three tables in the same db.
Tables:
1. cm_players
player_id
card_no
club_id
surname
name
birthdate
2. cm_clubs
club_id
prefix
name
address
place
stadium_id
telephone
fax
email
web
contact_person
president
secretary
press_officer
status
image
3. cm_registrations
player_id
surname
name
birthdate
birthplace
club_id
date_from
date_to
amateur
status
So, I need to display
cm_players.name,
cm_players.surname,
cm_clubs.name,
cm_players.birthdate,
cm_players.card_no,
join cm_players with cm_clubs to get the name of the club, and check in cm_registrations if the user is active.....
I have tried something like:
SELECT cm_players.name, cm_players.surname, cm_clubs.name, cm_players.birthdate, cm_players.card_no, cm_registrations.amateur FROM cm_players
INNER JOIN cm_clubs on cm_players.club_id = cm_clubs.club_id, cm_registrations
WHERE cm_players.name LIKE '%$name%' AND cm_players.surname LIKE '%$surname%' AND cm_players.player_id = cm_registrations.player_id AND cm_registrations.amateur = 0 ORDER BY cm_players.player_id ASC
but no luck...
can anyone help me to build this query?

Here we are setting the table aliases, and get the column values by using appropriate alias names of that table and we are using inner joins on two tables that are clubs and registrations
SELECT cmp.name, cmp.surname, cmc.name, cmp.birthdate, cmp.card_no, cmr.amateur
FROM cm_players cmp
INNER JOIN cm_clubs cmc on cmp.club_id = cmc.club_id
INNER JOIN cm_registrations cmr on cmp.player_id = cmr.player_id
WHERE cmp.name LIKE '%$name%'
AND cmp.surname LIKE '%$surname%'
AND cmr.amateur = 0
ORDER BY cmp.player_id ASC

cm_registrations WHERE cm_players.name LIKE '%$name%' AND cm_players.surname LIKE '%$surname%' AND cm_players.player_id = cm_registrations.player_id AND cm_registrations.amateur = 0 ORDER BY cm_players.player_id ASC
error is after join u use , than cm_registeration change it and try to fix it.

Related

How to export user data from two different tables using the backoffice sql manager of Prestashop?

I'm not good with sql so i need help exporting my customer's first names, email address, their country and if possible last times they had access to the store.
I managed to get email and first name by using this query :
SELECT firstname, lastname, email, active FROM psdb_customer
From what i understood, since the other data is stored in a different db table, i should use a join to get data from both tables but i haven't been able to figure out how
Any help is welcome
In the past, I helped someone with something similar in the PrestaShop forum. This query should work, just remember that to get a country of a customer they should have at least one address registered and of course I'm using the default db prefix:
SELECT a.`firstname`,
a.`lastname`,
a.`email`,
(SELECT c.`date_add`
FROM `ps_guest` g
LEFT JOIN `ps_connections` c ON c.`id_guest` = g.`id_guest`
WHERE g.`id_customer` = a.`id_customer`
ORDER BY c.`date_add` DESC LIMIT 1) AS `last_activity`,
(SELECT cl.`name`
FROM `ps_address` ad
LEFT JOIN `ps_country_lang` cl ON cl.`id_country` = ad.`id_country`
WHERE ad.`id_customer` = a.`id_customer`
ORDER BY ad.`id_address` DESC LIMIT 1) AS `country_name`
FROM `ps_customer` a
Rolige's answer is what i was looking for.
Here is another query that allows filtering the results by country (using the id_country)
SELECT SQL_CALC_FOUND_ROWS a.`id_address`,
a.firstname as firstname,
a.lastname as lastname,
cl.id_country as country, cl.`name` as country
FROM `ps_address` a
LEFT JOIN `ps_country_lang` cl ON (cl.`id_country` = a.`id_country`
AND cl.`id_lang` = 1)
LEFT JOIN `ps_customer` c ON a.id_customer = c.id_customer
WHERE 1 AND a.id_customer != 0
AND c.id_shop IN (1)
AND a.`deleted` = 0
AND cl.`id_country` = '8'
ORDER BY a.`id_address` ASC

how to Populating table with data returned from 3 joins tables

i have 4 tables
1. the first table(d_cities) for cities // related with the next table by country_id
CityId |CountryID |RegionID |City |Latitude|Longitude
2. the second table(d_country) for countries
CountryId|Country
3. the third table(ip2location_db11) for ip
ip_from|ip_to |country_code|country_name| city_name
4 the fourth table (ip_relation) would be like this
CountryID |CityId|ip_from |ip_to
i create the fourth table to collect custom data from the three tables and put it in one table..
this will has been done by :
join (d_country,d_cities) by id ,
then compare this names with IP table if matched
it will fetch the ids for these names & ips that matched and put it in the fourth table
..so i write my code like this and need to support to modify this code
INSERT ip_relations (CountryID, CityId,ip_from,ip_to)
SELECT *
FROM d_cities
INNER JOIN d_country ON d_cities.CountryID = d_country.CountryId
INNER JOIN ip2location_db11 ON ip2location_db11.country_name = d_country.Country
AND ip2location_db11.city_name = d_cities.City
/// this sql statement not work
first, i am not sure why do you design table like this.maybe you could change them like below:
d_cities: city_id | country_id | region_id |city | latitude| longitude
d_country: country_id | country
ip2location_db11: ip_from | ip_to | country_code | city_id
pS: I am not very sure what does country_code mean,so I keep it.base on the table structure above,it mostly like this: country to city is one-to-many and city_id must be unique, the ips is only have relation with the city_id.
I think ,this will be a better design...
then, if you have to solve the problem based on your current tables.
you would make a unique key "UNIQUE KEY uniq_from_to (ip_from,ip_to) "; and,there is sql:
INSERT IGNORE ip_relation
(SELECT cA.country_id,cA.city_id,ip.ip_from,ip.ip_to FROM ip2location_db11 ip
LEFT JOIN (SELECT cy.country,ct.city,ct.country_id,ct.city_id FROM d_country cy,d_cities ct WHERE cy.country_id = ct.country_id) as cA ON ip.city_name = cA.city AND ip.country_name = cA.country);
this means : 1.find All city-country groups;then based on the city-country groups;2.insert into your forth table,and when ip_from-ip_to is duplicate ,will cover the data before.
hope this can give you some help.
UPDATE ip_relations, ip2location_db11, d_cities, d_country
set ip_relations.countryid =d_country.CountryID
, ip_relations.cityid= d_cities.CityId
, ip_relations.ip_from=ip2location_db11.ip_from
, ip_relations.ip_to=ip2location_db11.ip_to
WHERE ip_relations.countryID=d_country.countryID and ip_relations.cityID=d_cities.CityID and ip_relations.ip_from=ip2location_db11.ip_from
and ip_relations.ip_to=ip2location_db11.ip_to;
Assuming country_id, city_id, countryname etc., being same through out all three tables:
SELECT
,dco.countryid AS countryid
,dci.cityid AS cityid
,ip_from
,ip_to
FROM d_country dco
INNER JOIN d_cities dci
ON dco.countryid=dci.countryid
INNER JOIN ip2location_db11 ip
ON TRIM(dci.city)=TRIM(ip.city_name)
AND TRIM(dco.country)=TRIM(ip.country_name)
WHERE dco.country_id=ip.country_code
UPDATE
ip_relation
FROM (
SELECT
,dco.countryid AS countryid
,dci.cityid AS cityid
,ip_from
,ip_to
FROM d_country dco
INNER JOIN d_cities dci
ON dco.countryid=dci.countryid
INNER JOIN ip2location_db11 ip
ON TRIM(dci.city)=TRIM(ip.city_name)
AND TRIM(dco.country)=TRIM(ip.country_name)
WHERE dco.country_id=ip.country_code
) DT
SET
ip_from=DT.ip_from
ip_to=DT.ip_to
WHERE CountryID=DT.countryid
AND CityId=DT.cityid
The correct way to join is here
UPDATE
ip_relations ir
INNER JOIN ip2location_db11 idl ON ir.ip_to = idl.ip_to
INNER JOIN ip2location_db11 idr ON ir.ip_from = idr.ip_from
INNER JOIN d_cities dc ON ir.d_cities = dc.d_cities
INNER JOIN d_country dct ON ir.countryID = dct.countryID
SET
ir.CountryID = dct.CountryID,
ir.CityId = dc.CityId,
ir.ip_from = dcr.ip_from,
ir.ip_to = dcl.ip_to
// put where condition if required
But when you are joining on some keys and want to update the keys i am sure all the keys will be same even after update so this will have no effect. If you update some else columns then it is practical.
To understand this assume this example.
joining two table on key which is 3. 3 is coming from 2nd table. updating column of first table with 3. So why do you need this? You need to update some else columns not the same ones you are joining.
INSERT INTO ip_relations (CityId,CountryID,ip_from,ip_to)
SELECT
d_cities.CityId,
d_cities.CountryID,
ip2location_db11.ip_from,
ip2location_db11.ip_to
FROM d_cities
INNER JOIN d_country ON d_cities.CountryID = d_country.CountryId
INNER JOIN ip2location_db11 ON ip2location_db11.country_name = d_country.Country
AND ip2location_db11.city_name = d_cities.City

How to obtain a relevance score in a table

I have a mysql table that has typetags for games, like
table game_typetags:
name typetag
--------- --------
game#1 sports
game#1 soccer
game#2 race
game#2 sports
and another table games like
name playcount
--------- ---------
game#1 10
game#2 8
And I want to list relevant games (score them with number of common typetags) and sort with playcount.
So I'm trying to get such an array in PHP:
function getSimilarGames($typetags_array)
{
$pdo->query("SELECT * FROM games COUNT (*) AS ???? ORDER BY games.playcount DESC");
}
So that when I call this function with $typetags = [race,sports] , it should return
name score
____ _____
game#2 2
game#1 1
What query should I use for this?
Thanks !
I do not agree with your database design, you should try to normalize it a bit but here is code that would work on your design:
SELECT games.name, COUNT(1) score
FROM games
INNER JOIN game_typetags ON game_typetags.name = games.name
WHERE game_typetags.typetag IN ('race', 'sports')
GROUP BY games.name
ORDER BY score DESC
I suggest a design like so;
game
-------
id integer pk
name varchar
typetag
-------
id integer pk
tagname varchar
game_typetags
-------
game_id int pk
typetag_id int pk
With this design you join together your tables using ID's instead of using strings everywhere.
A query to get the data you want from this could look like this, note that you could even use the tag-ids to make it tad faster (working on primary key in the database instead of string comparison in the where clause)
SELECT game.id, game.name, game.playcount, COUNT(1) score
FROM game
INNER JOIN game_typetags gtt ON gtt.game_id = game.id
INNER JOIN typetag tt ON tt.id = gtt.typetag_id
WHERE tt.typetag IN ('race', 'sports')
GROUP BY game.id
ORDER BY score DESC
And I figured out a solution to this problem, as follows:
SELECT name, SUM(matches) as relevance_score FROM
(
SELECT
game_typetags.*,
(typetag = 'race' )
+ (typetag = 'sports' )
AS matches
FROM game_typetags HAVING matches>0
ORDER BY matches DESC
) a GROUP BY name ;

Fetching a result twice with deferend name

I have 1 table with tasks named opentask:columns: id,title,description,expires,creator_id,creator_name, executer_id, executer_name, priority_id, status_id1 table with users named user:
with columns: user_id, username
What I want is to create a query where there will be all columns from opentask table where the executer_id will be equal to the user_id of user table AND the creator_id will be equal to the user_id again. This creates a confusion because the first equality excludes the second.So I need somehow to create a query where I will include the usernames for the executer with something like where "opentask.executer_id=user_user_id" and at the same time I will include the username again (as a differend name?) for the creator with something like "where opentask.executer_id=user_user_id"So I try this, which of course I know that is missing something, can you help?
SELECT DISTINCT id, title, description, expires, creator_id, executer_id, oc_opentask.priority_id, oc_opentask.status_id, priority_name, status_name, user_id, username, (SELECT username FROM oc_opentask, oc_user WHERE oc_opentask.creator_id=oc_user.user_id) AS username2 FROM oc_opentask, oc_opentask_priority, oc_user, oc_opentask_status WHERE oc_opentask.priority_id=oc_opentask_priority.priority_id AND oc_opentask.executer_id=oc_user.user_id AND oc_opentask.status_id=oc_opentask_status.status_id ORDER BY oc_opentask.expires DESC
ReJOIN the table oc_user twice with different aliases creators and executers like so:
SELECT DISTINCT
t.*,
creators.user_name 'Creator name',
executers.username 'Executor name',
tp.priority_name,
s.status_name
FROM oc_opentask t
INNER JOIN oc_opentask_priority tp ON t.priority_id = tp.priority_id
INNER JOIN oc_user executers ON t.executer_id = executes.user_id
INNER JOIN oc_user creators ON t.creator_id = creators.user_id
INNER JOIN oc_opentask_status s ON t.status_id = s.status_id
ORDER BY t.expires DESC

in mysql is it possible to sort results using one columns of a table if not empty or another table column

I have those two tables, Artist and Pseudonym, Artist belongsTo Pseudonym
I'd like to join the two tables and sort the result on Artist.lastname. Now, if he has a pseudonym, the pseudonym should be used, like in the example below, Balthus is between BACON and CHAGAL, even if his lastname starts with K
Artist.Lastname Pseudonym.name
BACON
KLOSSOWSKI Balthus
CHAGAL
CEZANNE
Is it possible to make a virtual column that has the pseudo if not empty or the lastname, and then sort on that column?
SELECT .....
FROM Artists as a
LEFT JOIN Pseudonyms as p ON (a.pseudonym_id = p.id)
ORDER BY the_virtual_column
...ORDER BY COALESCE(p.name, a.Lastname)
Try this:
SELECT .....
FROM Artists as a LEFT JOIN Pseudonyms as p
ON (a.pseudonym_id = p.id)
ORDER BY COALESCE(p.name , a.Lastname)