how to subsort of LEFT JOIN in MySQL query? - mysql

How can I build a query to sort the results by vl_name (vldescription) alphabetically, and subsort table vllinks by vlk_addeddate from the latest with internal limit equal to 1?
SELECT
aa.vl_id, aa.vl_name, aa.vl_code, aa.vl_vcc, aa.vl_description,
bb.vlk_id, bb.vlk_vlid, bb.vlk_link, bb.vlk_platform, bb.vlk_location, bb.vlk_addeddate,
le.vop_vlid, le.vop_thumbnail,
cx.vcc_id, cx.vcc_type, cx.vcc_brand, cx.vcc_variant
FROM vldescription AS aa
LEFT JOIN vllinks AS bb ON aa.vl_id = bb.vlk_vlid
LEFT JOIN vlofferphotos AS le ON le.vop_vlid = aa.vl_id
LEFT JOIN vlcarcats AS cx ON cx.vcc_id = aa.vl_vcc
WHERE aa.vl_vcc = '$change_me_if_you_need'
GROUP BY vl_id
ORDER BY vl_name
Table vlcarcats (vcc_
vcc_id | vcc_type | vcc_brand | vcc_variant
1 | OpenPlace | SomeCorp1 | website
2 | ForPrive | SomeCorp2 | other way
Table vldescription
vl_id | vl_name | vl_code | vl_vcc | vl_description
1 | OpTECC | xDAOcm | 1023 | text, text,...
2 | NewCop | d9MMo2 | 42 | more text,...
Table vllinks (vlk_vlid == vl_id)
vlk_id | vlk_vlid | vlk_link | vlk_platform | vlk_location | vlk_addeddate
1 | 1 | http://... | 1 | USA | 2014-01-10
2 | 2 | http://... | 1 | UK | 2014-01-12
3 | 2 | ftp://... | 2 | UK | 2014-01-15
4 | 2 | ftp://... | 2 | India | 2014-01-19
5 | 1 | ftp://... | 2 | Austria | 2014-01-22
Table vlofferphotos (vop_vlid == vl_id)
vop_vlid | vop_thumbnail
1 | abcdefg.jpg
2 | hijklmn.jpg

Related

Sum price of a table with reference to two others - Mysql

I have these three tables and I want to get the sum of the price field of table 3 linked to table 1, table 2 being linked to table 1 and 3:
Table 1 - Tecnic
+--------------+------------+
| id_tecnic | name |
+--------------+------------+
| 1 | Michael |
| 2 | Billy |
| 3 | Joe |
+--------------+------------+
Table 2 - Linked
+--------------+------------+------------+
| id_linked | id_tecnic | id_mer |
+--------------+------------+------------+
| 1 | 1 | 4 |
| 2 | 3 | 1 |
| 3 | 3 | 2 |
+--------------+------------+------------+
Table 3 - Mer
+--------------+------------+
| id_mer | price |
+--------------+------------+
| 1 | 30 |
| 2 | 70 |
| 3 | 50 |
| 4 | 10 |
+--------------+------------+
Result
+--------------+------------+-------------+
| id_tecnic | name | total_price |
+--------------+------------+-------------+
| 1 | Michael | 10 |
| 2 | Billy | 0 |
| 3 | Joe | 90 |
+--------------+------------+-------------+
I have tried this:
SELECT te.id_tecnic,
SUM(m.price)
FROM tecnic te
LEFT JOIN linked l ON te.id_tecnic = l.id_tecnic
LEFT JOIN mer m ON l.id_mer = m.id_mer
GROUP BY te.id_tecnic
Billy doesn't have record in Table 2 - Linked so with purpose to have Billy in result set you have to start from table Table 3 - Mer, like:
SELECT te.id_tecnic, te.name, SUM(m.price)
FROM mer m
LEFT jOIN linked l ON l.id_mer = m.id_mer
LEFT JOIN te ON te.id_tecnic = l.id_tecnic
GROUP BY te.id_tecnic;

SQL Query problem - difficult query with six tables

I need a help of a sql expert. I have a problem with my sql query. I have six MySQL tables:
pcs_persons (table of players)
+----+------------+------------+
| id | firstname | lastname |
+----+------------+------------+
| 1 | John | McClane |
| 2 | Jack | Marriott |
| 3 | Billy | Bravo |
| 4 | Archie | MacDonald |
+----+------------+------------+
pcs_matchs (table of match results)
+----+-------------------+-------------------+---------+------------+------------+
| id | id_candidate_dom | id_candidate_ext | id_day | id_season | id_compet |
+----+-------------------+-------------------+---------+------------+------------+
| 1 | 1 | 2 | 1 | 1 | 1 |
| 2 | 3 | 4 | 1 | 1 | 1 |
| 3 | 2 | 3 | 2 | 1 | 1 |
| 4 | 4 | 1 | 2 | 1 | 1 |
| 5 | 1 | 7 | 1 | 2 | 3 |
| 6 | 6 | 3 | 2 | 2 | 5 |
+----+-------------------+-------------------+---------+------------+------------+
pcs_lineup (table of those players who were selected to the match squad as starter - type 2, or as substitute - type 3)
+----+-----------+----------+------------+-------+
| id | id_match | id_club | id_person | type |
+----+-----------+----------+------------+-------+
| 1 | 1 | 1 | 1 | 2 |
| 2 | 1 | 1 | 2 | 3 |
| 3 | 1 | 2 | 3 | 2 |
| 4 | 1 | 2 | 4 | 3 |
+----+-----------+----------+------------+-------+
pcs_goals (table of scored goals by players)
| id | id_match | id_person | id_club | goal_min |
+----+-----------+------------+----------+-----------+
| 1 | 1 | 1 | 1 | 23 |
| 2 | 1 | 1 | 1 | 48 |
| 3 | 1 | 3 | 2 | 56 |
| 4 | 1 | 4 | 2 | 89 |
+----+-----------+------------+----------+-----------+
pcs_cards (table of received cards by players)
| id | id_match | id_person | id_club | card_min | card_yellow | card_red |
+----+-----------+------------+----------+-----------+--------------+-----------+
| 1 | 1 | 1 | 1 | 12 | 1 | |
| 2 | 1 | 1 | 1 | 43 | 1 | |
| 3 | 1 | 3 | 2 | 78 | | 1 |
| 4 | 1 | 4 | 2 | 91 | 1 | |
+----+-----------+------------+----------+-----------+--------------+-----------+
pcs_subs (table of substitutions)
| id | id_match | id_club | id_person_in | id_person_out | subs_min |
+----+-----------+----------+---------------+----------------+-----------+
| 1 | 1 | 1 | 7 | 1 | 82 |
| 2 | 1 | 1 | 8 | 2 | 85 |
| 3 | 1 | 2 | 5 | 3 | 89 |
| 4 | 1 | 2 | 6 | 4 | 91 |
+----+-----------+----------+---------------+----------------+-----------+
My current query is here:
SELECT pcs_lineup.id_person, pcs_lineup.id_club, pcs_lineup.type,
pcs_persons.lastname, pcs_persons.firstname, count( pcs_lineup.id_person) AS apps, count(pcs_subs.id_person_in) AS subs
FROM pcs_lineup
JOIN pcs_matchs ON pcs_matchs.id = pcs_lineup.id_match
JOIN pcs_persons ON pcs_persons.id = pcs_lineup.id_person
LEFT JOIN pcs_subs ON pcs_subs.id_person_in = pcs_lineup.id_person
WHERE pcs_lineup.id_club =2
AND pcs_matchs.id_compet =1
AND pcs_matchs.id_season =1
AND pcs_lineup.type = 2 OR pcs_subs.id_person_in IS NOT NULL AND pcs_subs.id_club =2
GROUP BY id_person
My current result structure (list of players who played as member of starting lineup or played as substitutes, players who just sat on the bench not counted)
+-----------+----------+-------+-----------+------------+-------+-------+
| id_person | id_club | type | lastname | firstname | apps | subs |
+-----------+----------+-------+-----------+------------+-------+-------+
I would like to add extra columns (goals, yellow cards, red cards) to the result, but I don't know how.
The structure of desired result:
+-----------+----------+-------+-----------+------------+-------+----------+-------+--------+---------------+------------+
| id_person | id_club | type | lastname | firstname | apps | starter | subs | goals | yellow cards | red_cards |
+-----------+----------+-------+-----------+------------+-------+----------+-------+--------+---------------+------------+
I hope that some expert could help for me, because I have no idea how could I join these tables for the desired result. Many thanks!
Modified code (results are not good)
SELECT pcs_lineup.id_person
,pcs_lineup.id_club
,pcs_lineup.type
,pcs_persons.lastname
,pcs_persons.firstname
,count( pcs_lineup.id_person) AS apps
,CASE WHEN pcs_lineup.type = 2 THEN 'YES' END starter
,count(pcs_subs.id_person_in) AS subs
,count(pcs_goals.goal_min) AS goals
,count(card_yellow) as "Yellow Cards"
,count(card_red) as "Red Card"
FROM pcs_lineup
JOIN pcs_matchs ON pcs_matchs.id = pcs_lineup.id_match
JOIN pcs_persons ON pcs_persons.id = pcs_lineup.id_person
LEFT JOIN pcs_subs ON pcs_subs.id_person_in = pcs_lineup.id_person
LEFT JOIN pcs_goals ON pcs_goals.id_match = pcs_matchs.id
AND pcs_persons.id = pcs_goals.id_person
LEFT JOIN pcs_cards ON pcs_cards.id_match = pcs_matchs.id
AND pcs_cards.id_person = pcs_persons.id
AND pcs_goals.id_club = pcs_cards.id_club
WHERE pcs_lineup.id_club =2
AND pcs_matchs.id_compet =1
AND pcs_matchs.id_season =1
AND pcs_subs.id_person_in IS NOT NULL AND pcs_subs.id_club =2
GROUP BY id_person
You need to join 2 more tables i.e. pcs_goals and pcs_cards -
SELECT pcs_lineup.id_person
,pcs_lineup.id_club
,pcs_lineup.type
,pcs_persons.lastname
,pcs_persons.firstname
,count( pcs_lineup.id_person) AS apps
,CASE WHEN pcs_lineup.type = 2 THEN 'YES' END starter
,count(pcs_subs.id_person_in) AS subs
,count(pcs_goals.goals_min) AS goals
,count(card_yellow) as "Yellow Cards"
,count(card_red) as "Red Card"
FROM pcs_lineup
JOIN pcs_matchs ON pcs_matchs.id = pcs_lineup.id_match
JOIN pcs_persons ON pcs_persons.id = pcs_lineup.id_person
LEFT JOIN pcs_subs ON pcs_subs.id_person_in = pcs_lineup.id_person
LEFT JOIN pcs_goals ON pcs_goals.id_match = pcs_matchs.id
AND pcs_persons.id = pcs_matchs.id_person
LEFT JOIN pcs_cards ON pcs_cards.id_match = pcs_matchs.id
AND pcs_cards.id_person = pcs_persons.id
AND pcs_goals.id_club = pcs_cards.id_club
WHERE pcs_lineup.id_club =2
AND pcs_matchs.id_compet =1
AND pcs_matchs.id_season =1
AND pcs_subs.id_person_in IS NOT NULL AND pcs_subs.id_club =2
GROUP BY id_person
I am not sure what do you mean by starter column.
pcs_subs.id_person_in change to id_person_out

Mysql, repeat row by the max count of details

I have two tables
Master table
|-----------|--------|------------|
| id_client | name | ci |
|-----------|--------|------------|
| 1 | B | 123 |
| 2 | A | 234 |
| 3 | C | 345 |
|-----------|--------|------------|
Detail of equipments
|-----------|--------------|
| id_client | id_equipment |
|-----------|--------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
|-----------|--------------|
The result that I expected is:
All clientes with or without equipments
|-----------|----------------|----------------|
| id_client | id_equipment | numberEquipment|
|-----------|----------------|----------------|
| 1 | 1 | Equip1 |
| 1 | 2 | Equip2 |
| 2 | 3 | Equip1 |
| 2 | - | Equip2 |
| 3 | - | Equip1 |
| 3 | - | Equip2 |
|-----------|----------------|----------------|
Client 1 have two equipments and this is the max cant of equipments assigned, then, all clientes with minor than two have to fill the detail empty two times. client 2 have one equipment assigned, the second will be empty, and cliente 3 doesnt have any equipment, then the two equipments will be empty.
I was implemented crosstab on jasperreport, i have to define de columnGroup, when the name of group Equipment1, equipment2... etc, doesnt exist on any row this column group doesnt show.
I hope someone can helpme.
Thanks.
SELECT CONCAT('EQUIPMENT ',g.ennum) AS numberEquipment,
g.ID_CLIENTE as id_client, g.ID_EQUIPO as id_equipment,
(SELECT #running1:= 0) AS running1,(SELECT #previous1:= 0) AS previous1
FROM (
SELECT c.ID_CLIENTE, eq.ID_EQUIPO
#running1:=if(#previous1=concat(eq.ID_CLIENTE),#running1,0) + 1 as ennum, #previous1:=concat(eq.ID_CLIENTE)
FROM CLIENTE AS c
LEFT JOIN detail_equipments AS eq ON eq.ID_CLIENTE = c.ID_CLIENTE
ORDER BY c.ID_CLIENTE ) AS g
GROUP BY g.ID_CLIENTE, g.ID_EQUIPO
ORDER BY ID_CLIENTE, g.ennum
this show
|-----------|----------------|----------------|
| id_client | id_equipment | numberEquipment|
|-----------|----------------|----------------|
| 1 | 1 | Equip1 |
| 1 | 2 | Equip2 |
| 2 | 3 | Equip1 |
| 3 | - | Equip1 |
|-----------|----------------|----------------|

mysql: comparing two columns

my tables and their layout:
mysql> select * FROM xt_shipping_zones;
+---------+-------------+---------------------------------------------------------------------------+
| zone_id | zone_name | zone_countries |
+---------+-------------+---------------------------------------------------------------------------+
| 5 | ZONE1 | AT,BE,BG,DK,FI,FR,GR,IE,IT,LV,LT,LU,MC,NL,PL,PT,RO,SM,SE,SK,SI,ES,HU,GB |
| 6 | Deutschland | DE |
| 8 | ZONE2Brutto | AD,NO,VA |
| 9 | ZONE2NETTO | CH,LI |
+---------+-------------+---------------------------------------------------------------------------+
mysql> select * FROM xt_shipping_cost WHERE shipping_geo_zone = 99995 LIMIT 5;
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
| shipping_cost_id | shipping_id | shipping_geo_zone | shipping_country_code | shipping_type_value_from | shipping_type_value_to | shipping_price | shipping_allowed |
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
| 269 | 34 | 99995 | | 0.31 | 17.99 | 17.0000 | 1 |
| 270 | 34 | 99995 | | 17.99 | 35.99 | 34.0000 | 1 |
| 271 | 34 | 99995 | | 35.99 | 53.99 | 51.0000 | 1 |
| 272 | 34 | 99995 | | 53.99 | 71.99 | 68.0000 | 1 |
| 273 | 34 | 99995 | | 71.99 | 89.99 | 85.0000 | 1 |
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
mysql> SELECT * FROM geoip WHERE 92569600 BETWEEN start AND end;
+----------+----------+---------+-----+
| start | end | country | id |
+----------+----------+---------+-----+
| 92569600 | 92585983 | AT | 895 |
+----------+----------+---------+-----+
My Query:
SELECT
xt_shipping_cost.shipping_type_value_from,
xt_shipping_cost.shipping_type_value_to,
xt_shipping_cost.shipping_price,
geoip.country
FROM xt_shipping_cost
INNER JOIN xt_shipping_zones
ON xt_shipping_cost.shipping_geo_zone = xt_shipping_zones.zone_id + 99990
INNER JOIN geoip
ON geoip.country REGEXP xt_shipping_zones.zone_countries
WHERE 34664448 BETWEEN geoip.start AND geoip.end
My Problem:
Query is working if there is only ONE entry in xt_shipping_zones.zone_countries like DE. If there are multiple (with comma seperated entries) i cant get a match on that row.
Doing it manually:
mysql> SELECT * FROM `xt_shipping_zones` WHERE `zone_countries` REGEXP 'AT';
+---------+-----------+---------------------------------------------------------------------------+
| zone_id | zone_name | zone_countries |
+---------+-----------+---------------------------------------------------------------------------+
| 5 | ZONE1 | AT,BE,BG,DK,FI,FR,GR,IE,IT,LV,LT,LU,MC,NL,PL,PT,RO,SM,SE,SK,SI,ES,HU,GB |
+---------+-----------+---------------------------------------------------------------------------+
SQLFiddle: http://sqlfiddle.com/#!9/68f8d0/1
I hope i didn't failed to much to make my problem clear.
Thank you
I think you can use find_in_set()
SELECT
xt_shipping_cost.shipping_type_value_from,
xt_shipping_cost.shipping_type_value_to,
xt_shipping_cost.shipping_price,
geoip.country
FROM xt_shipping_cost
INNER JOIN xt_shipping_zones
ON xt_shipping_cost.shipping_geo_zone = xt_shipping_zones.zone_id + 99990
INNER JOIN geoip
ON find_in_set(geoip.country, xt_shipping_zones.zone_countries)
WHERE 34664448 BETWEEN geoip.start AND geoip.end
It is no good idea to store the values as csv. That is very bad database design.

How should I write this MySQL query containing multiple Left Joins

I have a query consisting of multiple joins and I am wondering whether it can be re-written to improve performance.
I have 2 tables as follows (I have removed non-important columns for this example):
slots
------------------------------------------
| id | name | slot_1 | slot_2 | slot_3 |
------------------------------------------
| 1 | Bob | 1 | 2 | 3 |
| 2 | Jim | 4 | 3 | 3 |
| 3 | Alf | 1 | 2 | 5 |
------------------------------------------
(There are 25 slots in total, each in it's own column)
slot_details
-----------------------------------
| id | stat_1 | stat_2 | stat_3 |
-----------------------------------
| 1 | 1 | 5 | 6 |
| 2 | 4 | 31 | 23 |
| 3 | 6 | 5 | 7 |
| 4 | 7 | 4 | 9 |
| 5 | 2 | 3 | 5 |
-----------------------------------
(There are 10 stats in total)
The query is as follows:
SELECT
slots.name,
slot_1_details.stat_1 AS slot_1_stat_1,
slot_1_details.stat_2 AS slot_1_stat_2,
slot_1_details.stat_3 AS slot_1_stat_3,
slot_2_details.stat_1 AS slot_2_stat_1,
slot_2_details.stat_2 AS slot_2_stat_2,
slot_2_details.stat_3 AS slot_2_stat_3,
slot_3_details.stat_1 AS slot_3_stat_1,
slot_3_details.stat_2 AS slot_3_stat_2,
slot_3_details.stat_3 AS slot_3_stat_3
FROM
slots
LEFT JOIN
slot_details AS slot_1_details
ON (
slot_1_details.id = slots.slot_1
)
LEFT JOIN
slot_details AS slot_2_details
ON (
slot_2_details.id = slots.slot_2
)
LEFT JOIN
slot_details AS slot_3_details
ON (
slot_3_details.id = slots.slot_3
)
WHERE (
slots.id = 1
)
The expected outcome of this query would be as follows:
| name | slot_1_stat_1 | slot_1_stat_2 | slot_1_stat_3 | slot_2_stat_1 | slot_2_stat_2 | slot_2_stat_3 | slot_3_stat_1 | slot_3_stat_2 | slot_3_stat_3 |
|bob | 1 | 5 | 6 | 4 | 31 | 23 | 6 | 5 | 7 |
Unfortunately I am not in a situation where I can change the tables.
Thank you for the help!
maybe
SELECT * FROM slots s LEFT JOIN slot_details sd ON s.id=sd.id
but i'm not sure because the query you posted is very confusing.
what are the keys of those tables?