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
Related
From the following game table of sports matches:
+-----+-----------+---------------+----------+-------+-------+---------+---------+
| id_ | date_time | tournament_id | round_id | p1_id | p2_id | p1_stat | p2_stat |
+-----+-----------+---------------+----------+-------+-------+---------+---------+
| 1 | NULL | 1 | 4 | 1 | 3 | 2 | 3 |
| 2 | NULL | 1 | 5 | 1 | 4 | 4 | 6 |
| 3 | NULL | 1 | 9 | 1 | 5 | 6 | 9 |
| 4 | NULL | 1 | 10 | 2 | 1 | 8 | 12 |
| 5 | NULL | 2 | 4 | 1 | 2 | 10 | 15 |
| 6 | NULL | 2 | 5 | 4 | 1 | 12 | 18 |
+-----+-----------+---------------+----------+-------+-------+---------+---------+
I'm trying to get the stats for each player for their previous match. The output should look like this:
+-----+--------------+--------------+
| id_ | prev_p1_stat | prev_p2_stat |
+-----+--------------+--------------+
| 1 | NULL | NULL |
| 2 | 2 | NULL |
| 3 | 4 | NULL |
| 4 | NULL | 6 |
| 5 | 12 | 8 |
| 6 | 6 | 10 |
+-----+--------------+--------------+
However, the date_time column is quite often blank and id_ is not date sequential. The tournament table does have a date_time column which is always populated:
+-----+------------+
| id_ | date_time |
+-----+------------+
| 1 | 1997-01-01 |
| 2 | 1997-01-06 |
+-----+------------+
This means the tournament date_time can be used in conjunction with game round_id to determine the previous match.
I've found the following answers here and here but they both focus on a single table and don't have the added complexity of having to determine whether the p1_stat or the p2_stat should be selected.
I've got as far as this query:
SELECT
g.id_ AS game_id,
CASE
WHEN g.p1_id = sq_p1.p1_id THEN sq_p1.p1_stat
ELSE sq_p1.p2_stat
END AS prev_p1_stat,
CASE
WHEN g.p1_id = sq_p2.p1_id THEN sq_p2.p1_stat
ELSE sq_p2.p2_stat
END AS prev_p2_stat
FROM
test.game AS g
JOIN
test.tournament AS t ON t.id_ = g.tournament_id
LEFT OUTER JOIN
(SELECT
g.id_ AS match_id,
t.date_time AS tournament_date,
g.round_id,
g.p1_id,
g.p2_id,
g.p1_stat,
g.p2_stat
FROM
test.game AS g
JOIN test.tournament AS t ON t.id_ = g.tournament_id) AS sq_p1 ON (sq_p1.p1_id = g.p1_id
OR sq_p1.p2_id = g.p1_id)
AND (sq_p1.tournament_date = t.date_time
AND sq_p1.round_id < g.round_id
OR sq_p1.tournament_date < t.date_time)
LEFT OUTER JOIN
(SELECT
g.id_ AS match_id,
t.date_time AS tournament_date,
g.round_id,
g.p1_id,
g.p2_id,
g.p1_stat,
g.p2_stat
FROM
test.game AS g
JOIN test.tournament AS t ON t.id_ = g.tournament_id) AS sq_p2 ON (sq_p2.p1_id = g.p1_id
OR sq_p2.p2_id = g.p1_id)
AND (sq_p2.tournament_date = t.date_time
AND sq_p2.round_id < g.round_id
OR sq_p2.tournament_date < t.date_time)
ORDER BY t.date_time , g.round_id
But this isn't even close to what I'm looking for :(
I've created a dbfiddle.
One other thing that's perhaps worth mentioning... I intend to use a couple of versions of this query in a union query such that the final result (including all columns for reference) will look like this:
+-----+------------+-----------+-------------+-------------+---------------+------------------+--------------------+
| id_ | player_num | player_id | opponent_id | player_stat | opponent_stat | player_prev_stat | opponent_prev_stat |
+-----+------------+-----------+-------------+-------------+---------------+------------------+--------------------+
| 1 | 1 | 1 | 3 | 2 | 3 | NULL | NULL |
| 1 | 2 | 3 | 1 | 3 | 2 | NULL | NULL |
| 2 | 1 | 1 | 4 | 4 | 6 | 2 | NULL |
| 2 | 2 | 4 | 1 | 6 | 4 | NULL | 2 |
| 3 | 1 | 1 | 5 | 6 | 9 | 4 | NULL |
| 3 | 2 | 5 | 1 | 9 | 6 | NULL | 4 |
| 4 | 1 | 2 | 1 | 8 | 12 | NULL | 6 |
| 4 | 2 | 1 | 2 | 12 | 8 | 6 | NULL |
| 5 | 1 | 1 | 2 | 10 | 15 | 12 | 8 |
| 5 | 2 | 2 | 1 | 15 | 10 | 8 | 12 |
| 6 | 1 | 4 | 1 | 12 | 18 | 6 | 10 |
| 6 | 2 | 1 | 4 | 18 | 12 | 10 | 6 |
+-----+------------+-----------+-------------+-------------+---------------+------------------+--------------------+
Perhaps it makes more sense to do a union and then engineer the previous stats?
For some final info, the actual game table has about 1.5m rows and the actual tournament table has about 30k rows. I'm using MySQL 8.0.26.
Kudos to #Barmer for the direction - here's the query I created using LAG():
WITH union_matches AS (
SELECT
g.id_ AS match_id,
t.date_time AS tournament_date,
g.round_id AS round_id,
1 AS player_num,
g.p1_id AS player_id,
g.p2_id AS opponent_id,
g.p1_stat AS player_stat,
g.p2_stat AS opponent_stat
FROM
game AS g
JOIN
tournament AS t ON t.id_ = g.tournament_id
UNION SELECT
g.id_ AS match_id,
t.date_time AS tournament_date,
g.round_id AS round_id,
2 AS player_num,
g.p2_id AS player_id,
g.p1_id AS opponent_id,
g.p2_stat AS player_stat,
g.p1_stat AS opponent_stat
FROM
game AS g
JOIN
tournament AS t ON t.id_ = g.tournament_id
)
SELECT
match_id,
player_num,
player_id,
opponent_id,
player_stat,
opponent_stat,
LAG(player_stat, 1) OVER (PARTITION BY player_id ORDER BY tournament_date, round_id) AS wrong_player_prev_stat,
LAG(opponent_stat, 1) OVER (PARTITION BY opponent_id ORDER BY tournament_date, round_id) AS wrong_opponent_prev_stat
FROM
union_matches
ORDER BY
tournament_date, round_id, player_num
And a link to the dbfiddle.
I am setting up a virtual classroom in PHP and MySQL. This classroom consists of courses and each course contains different subjects or modules. The student has to examine each module and, finally, a summary (evaluation board) is made to know if the student has passed the course or not.
Having said that, I have a table in which I store the evaluations of each student, in which I keep inscripcion_id (student - inscription_id), modulo_id (module_id), fecha (date_of_examination), aciertos (number_of_right_answers), ultima_convocatoria (evaluation_last_convocatory) and estado (status).
SQL Fiddle -> here
Through some previously established rules that tell me if a student has passed a module or not, I get the following set of data:
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| inscripcion_id | modulo_id | fecha | aciertos | ultima_convocatoria | estado | ev |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| 890 | 1 | 2018-01-24 22:26:09 | 8 | 2 | 1 | aprobado |
| 890 | 2 | 2018-01-24 22:36:58 | 3 | 3 | 0 | suspendido |
| 890 | 5 | 2018-01-24 22:38:50 | 3 | 1 | 0 | suspendido |
| 890 | 6 | 2018-01-24 22:44:20 | 7 | 3 | 0 | suspendido |
| 891 | 1 | 2018-01-25 09:24:42 | 8 | 1 | 1 | aprobado |
| 891 | 2 | 2018-01-25 10:01:55 | 4 | 8 | 0 | suspendido |
| 891 | 4 | 2018-01-25 10:51:49 | 5 | 3 | 1 | suspendido |
| 891 | 5 | 2018-01-25 10:23:45 | 9 | 1 | 1 | aprobado |
| 891 | 6 | 2018-01-25 11:21:20 | 7 | 3 | 0 | suspendido |
| 896 | 1 | 2018-01-25 11:55:48 | 1 | 1 | 1 | suspendido |
| 898 | 1 | 2018-01-25 14:01:51 | 6 | 1 | 1 | suspendido |
| 907 | 1 | 2018-03-25 16:06:18 | 3 | 1 | 0 | suspendido |
| 907 | 2 | 2018-03-25 16:07:34 | 3 | 1 | 0 | suspendido |
| 907 | 3 | 2018-03-25 16:09:04 | 3 | 1 | 0 | suspendido |
| 907 | 4 | 2018-03-25 16:08:13 | 3 | 1 | 0 | suspendido |
| 907 | 5 | 2018-03-25 16:10:37 | 2 | 1 | 0 | suspendido |
| 907 | 6 | 2018-03-25 16:08:44 | 3 | 1 | 0 | suspendido |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
This data is obtained through the following query:
SELECT e1.inscripcion_id,
e1.modulo_id,
e1.fecha,
e1.aciertos,
e1.convocatoria AS ultima_convocatoria,
e1.estado,
if (
( e1.modulo_id in (SELECT modulo.modulo_id FROM modulo WHERE modulo.curso_id = 1 AND modulo.categoria_id = 1)
AND e1.aciertos <= 7 )
OR ( e1.modulo_id = (SELECT modulo.modulo_id FROM modulo WHERE modulo.curso_id = 1 AND modulo.categoria_id = 2)
AND e1.aciertos <= 11 ),
"suspendido",
"aprobado"
) AS ev
FROM (
SELECT inscripcion_id,
modulo_id,
MAX(convocatoria) AS max_convocatoria
FROM `evaluacion`
GROUP BY inscripcion_id,
modulo_id
ORDER BY `inscripcion_id` ASC,
`modulo_id` ASC,
`convocatoria` ASC
) AS e2
INNER JOIN evaluacion AS e1
ON e1.inscripcion_id = e2.inscripcion_id
AND e1.modulo_id = e2.modulo_id
AND e1.convocatoria = e2.max_convocatoria
As you can see, the student 890, has made modules 1, 2, 5 and 6. What I want to achieve is that the modules that are still pending, I also get as a result in the previous data set. The exemplification:
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| inscripcion_id | modulo_id | fecha | aciertos | ultima_convocatoria | estado | ev |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| 890 | 1 | 2018-01-24 22:26:09 | 8 | 2 | 1 | aprobado |
| 890 | 2 | 2018-01-24 22:36:58 | 3 | 3 | 0 | suspendido |
| 890 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 890 | 4 | NULL | NULL | NULL | NULL | pendiente |
| 890 | 5 | 2018-01-24 22:38:50 | 3 | 1 | 0 | suspendido |
| 890 | 6 | 2018-01-24 22:44:20 | 7 | 3 | 0 | suspendido |
| 891 | 1 | 2018-01-25 09:24:42 | 8 | 1 | 1 | aprobado |
| 891 | 2 | 2018-01-25 10:01:55 | 4 | 8 | 0 | suspendido |
| 891 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 891 | 4 | 2018-01-25 10:51:49 | 5 | 3 | 1 | suspendido |
| 891 | 5 | 2018-01-25 10:23:45 | 9 | 1 | 1 | aprobado |
| 891 | 6 | 2018-01-25 11:21:20 | 7 | 3 | 0 | suspendido |
| 896 | 1 | 2018-01-25 11:55:48 | 1 | 1 | 1 | suspendido |
| 896 | 2 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 4 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 5 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 6 | NULL | NULL | NULL | NULL | pendiente |
| ... | | | | | | |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
The result is that the modules that the student has not yet done have been added, with the new value "pending" for the ev column.
I have no idea how to do this ... I've tried, I searched the internet and nothing :(
What is the final objective? What I want is to obtain a final list with all those students who have the pending course (that is, they have some pending module/s), to send them a reminder email that they have to examine themselves of the remaining modules. To those who have approved or suspended, no email will be sent to them.
Can you help me?
SQL Fiddle -> here
THANK YOU VERY MUCH
Suppose you want to get students with no module in evaluation table as 'pending' like what you provided in the example. The way to get student joining all module is to do a full join on modulo and evaluacion to get full set of distinct inscripcion_id modulo_id. Then left join with your existing query will provide the result you want.
sqlfiddle
SELECT fs.inscripcion_id,
fs.modulo_id,
e3.fecha,
e3.aciertos,
e3.ultima_convocatoria,
e3.estado,
IF(e3.ev IS NULL, "pendiente", e3.ev) AS ev
FROM (SELECT m.modulo_id,
e.inscripcion_id
FROM modulo m,
evaluacion e
GROUP BY m.modulo_id,
e.inscripcion_id) AS fs
LEFT JOIN (SELECT
e1.inscripcion_id,
e1.modulo_id,
e1.fecha,
e1.aciertos,
e1.convocatoria
AS
ultima_convocatoria
,
e1.estado,
IF (( e1.modulo_id IN (SELECT modulo.modulo_id
FROM modulo
WHERE modulo.curso_id = 1
AND modulo.categoria_id =
1)
AND e1.aciertos <= 7 )
OR ( e1.modulo_id = (SELECT modulo.modulo_id
FROM modulo
WHERE
modulo.curso_id = 1
AND modulo.categoria_id = 2)
AND e1.aciertos <= 11 ), "suspendido",
"aprobado")
AS ev
FROM (SELECT inscripcion_id,
modulo_id,
Max(convocatoria) AS max_convocatoria
FROM `evaluacion`
GROUP BY inscripcion_id,
modulo_id
ORDER BY `inscripcion_id` ASC,
`modulo_id` ASC,
`convocatoria` ASC) AS e2
INNER JOIN evaluacion AS e1
ON e1.inscripcion_id = e2.inscripcion_id
AND e1.modulo_id = e2.modulo_id
AND e1.convocatoria = e2.max_convocatoria)
AS e3
ON fs.modulo_id = e3.modulo_id
AND fs.inscripcion_id = e3.inscripcion_id
ORDER BY fs.inscripcion_id,
fs.modulo_id;
For the further question,
You may want to use
SELECT inscripcion_id,
SUM(case when ev = 'aprobado' then 1 else 0 end) as approved_cnt,
SUM(case when ev = 'suspendido' then 1 else 0 end) as suspended_cnt,
SUM(case when ev = 'pendiente' then 1 else 0 end) as pending_cnt
From --the above query...
Group by inscripcion_id
to get the count of status for each student, and then do the logic using those count.
After reviewing the new sqlfiddle
I wrote the query below, I think it should cover what you want
Notice that you more than one evaluation per module, meaning that you'll get more than one status per module
To solve that, you can add a group statement (in comment now)
Or you the different evaluations to your needs...
SELECT
i.inscripcion_id,
c.curso_id,
c.titulo AS curso_titulo,
m.modulo_id,
m.titulo AS modulo_titulo,
IFNULL(ev.estado,0) AS estado,
m.*
FROM
inscripcion i
INNER JOIN curso c ON c.curso_id = i.curso_id
INNER JOIN modulo m ON m.curso_id = c.curso_id
LEFT JOIN evaluacion ev ON ev.modulo_id = m.modulo_id
WHERE
(ev.estado = 0 OR ev.estado IS NULL)
/*
GROUP BY
m.modulo_id
*/
;
i try select all columns from two different tables WHERE active = 1
i have 2 tables table_pro and table_basic,
sql:"select * from table_basic,table.name";
and 2 condition:
WHERE active = 1
WHERE table_pro.id = table_basic.name.id
how to make it correctly
Here is table_pro
+----+--------+---------+-----------+
| id | people | rooms | active |
+----+--------+---------+-----------+
| 1 | 5 | 10 | 0 |
| 2 | 12 | 17 | 0 |
| 3 | 21 | 38 | 1 |
+----+--------+---------+-----------+
Here is table_basic
+---------+-------+---------+------------+----------+
| name_id | name | balance | title | time |
+---------+-------+---------+------------+----------+
| 1 |shop | 100 | failed | 15:10:20 |
| 2 |factory| 75 | error | 15:10:20 |
| 3 |studio | 25 | timed_out | 15:10:20 |
+---------+-------+---------+------------+----------+
I'd like to have this output result only rows (from of all columns) with status active = 1
+-----+-------+----- --+--------+-------+----------+---------+--------+
| id | people| rooms | name |balance| title | time | active |
+-----+-------+--------+--------+-------+----------+---------+--------+
| 3 | 21 | 38 | studio |25 | timed_out| 15:10:20| 1 |
+-----+-------+--------+--------+-------+----------+---------+--------+
Thanks
SELECT A.id, A.people, A.rooms, B.name, B.balance, B.title, B.time, A.active
FROM
table_pro AS A
JOIN
table_basic AS B
ON
A.id = B.name_id
WHERE
A.id = 3
SELECT table_pro.*, table_basic.*
FROM table_pro
INNER JOIN table_basic
ON table_basic.name_id = table_pro.id
WHERE table_pro.active = 1
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
Three table as follow
mysql> select * from food;
+--------+------+-------+
| foodid | name | price |
+--------+------+-------+
| 1 | 雞 | 100 |
| 2 | 鴨 | 200 |
| 3 | 魚 | 300 |
| 4 | 肉 | 400 |
+--------+------+-------+
4 rows in set
mysql> select * from drink;
+---------+------+-------+
| drinkid | name | price |
+---------+------+-------+
| 1 | 紅茶 | 50 |
| 2 | 綠茶 | 100 |
| 3 | 奶茶 | 150 |
+---------+------+-------+
3 rows in set
mysql> select * from order_table;
+----+-----------+--------+---------+------------+-------------+-------------+
| id | user_name | foodid | drinkid | food_count | drink_count | total_price |
+----+-----------+--------+---------+------------+-------------+-------------+
| 2 | 小明 | 3 | 2 | 2 | 2 | 0 |
| 3 | 小華 | 1 | 1 | 1 | 8 | 0 |
| 4 | 小英 | 1 | 3 | 3 | 3 | 0 |
| 6 | 小a | 2 | 1 | 4 | 6 | 0 |
| 7 | 小b | 2 | 2 | 5 | 4 | 0 |
| 8 | 小c | 2 | 3 | 6 | 10 | 0 |
| 9 | 大A | 3 | 1 | 9 | 8 | 0 |
| 10 | 大B | 3 | 2 | 5 | 4 | 0 |
| 11 | 大C | 3 | 3 | 10 | 3 | 0 |
+----+-----------+--------+---------+------------+-------------+-------------+
foodid in order_table is link to foodid in food table,
drinkid in order_table is link to drinkid in drink table,
Now, I want to calculate total price,
Total_price =
order_table.foodid(food.price in food table) * order_table.food_count +
order_table.drinkid(drink.price in drink table) * order_table.drink_count;
So, let me knowlege the command to update total price
thx a lot.
The reason why I used LEFT JOIN on the following query is because I assumed that some orders may only contain drinks or foods.
UPDATE order_table a
LEFT JOIN food b
ON a.foodid = b.foodID
LEFT JOIN drink c
ON a.drinkID = c.drinkID
SET a.total_price = (a.food_count * COALESCE(b.price, 0) +
a.drink_count * COALESCE(c.price, 0))
SQLFiddle Demo
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Something like this should be close:
SELECT COALESCE(F.Price,0)*OT.Food_Count+COALESCE(D.Price,0)*OT.Drink_Count Total_price
FROM Order_Table OT
LEFT JOIN Food F ON OT.FoodId = F.FoodId
LEFT JOIN Drink D ON OT.DrinkId = D.DrinkId
And to actually update that column:
UPDATE Order_Table OT
LEFT JOIN Food F ON OT.FoodId = F.FoodId
LEFT JOIN Drink D ON OT.DrinkId = D.DrinkId
SET OT.Total_Price = COALESCE(F.Price,0)*OT.Food_Count+COALESCE(D.Price,0)*OT.Drink_Count