Integer incremented by line displayed - mysql

This is team table :
+----+-------+--------+-------+
| id | alias | pwd | score |
+----+-------+--------+-------+
| 1 | login | mdp | 5 |
| 2 | azert | qsdfgh | 50 |
| 3 | test | test | 780 |
+----+-------+--------+-------+
This is activity table
+----+--------------+---------------------+-------+--------+
| id | localisation | name | point | answer |
+----+--------------+---------------------+-------+--------+
| 1 | Madras | Lancement du projet | 0 | NULL |
| 2 | Valparaiso | act1 | 450 | un |
| 3 | Amphi | act2 | 45 | deux |
| 4 | Amphix | act3 | 453 | trois |
| 5 | Amphix | act4 | 45553 | qautre |
| 6 | Madras | Lancement du projet | 0 | NULL |
| 7 | Valparaiso | act1 | 450 | un |
| 8 | Amphi | act2 | 45 | deux |
| 9 | Amphix | act3 | 453 | trois |
| 10 | Amphix | act4 | 40053 | fin |
+----+--------------+---------------------+-------+--------+
This is feed table :
+--------+---------------------+------------+--------+
| FeedId | ts | ActivityId | TeamId |
+--------+---------------------+------------+--------+
| 1 | 2023-01-10 00:02:06 | 1 | 3 |
| 2 | 2023-01-10 00:02:28 | 2 | 3 |
| 3 | 2023-01-10 00:21:13 | 3 | 3 |
| 4 | 2023-01-10 00:24:49 | 3 | 3 |
| 5 | 2023-01-10 00:30:58 | 1 | 1 |
+--------+---------------------+------------+--------+
I did this
MariaDB [sae]> SELECT #rownum:=#rownum+1 as 'Classement', t.alias, SUM(a.point) as total_points FROM activity a INNER JOIN feed f ON a.id = f.ActivityId INNER JOIN team t ON f.TeamId = t.id JOIN (SELECT #rownum:=0) r GROUP BY t.alias ORDER BY total_points DESC, Classement DESC;
+------------+-------+--------------+
| Classement | alias | total_points |
+------------+-------+--------------+
| 2 | test | 540 |
| 1 | login | 0 |
+------------+-------+--------------+
Here the team with the highest number of points contains the ranking 2 instead of one and if I sort by ASC Ranking it does not change anything.
I wish to this :
+------------+-------+--------------+
| Classement | alias | total_points |
+------------+-------+--------------+
| 1 | test | 540 |
| 2 | login | 0 |
+------------+-------+--------------+
Do you have any idea how to go about incrementing this "backwards" integer?

Unless you are using an eoled version of MariaDB you should use WINDOW function RANK() instead of dealing with user variables.
Working with user variable increment returns the same value as ROW_NUMBER() but this is not correct, since teams with the same score should get the same ranking.
SELECT RANK() OVER (ORDER BY subq.total_points DESC) AS 'Classement',
subq.* FROM (
SELECT team.alias, SUM(activity.point) AS total_points FROM activity
JOIN feed ON activity.id = feed.ActivityId
JOIN team ON feed.TeamId = team.id GROUP BY team.alias ) AS subq

This will handle the case if two or more teams have the same score. both of them will have the same ranking :
This is compatible with all versions of mysql and mariadb.
select #rank := CASE
WHEN #totalval = total_points THEN #rank
WHEN (#totalval := total_points) IS NOT NULL THEN #rank + 1
WHEN (#totalval := total_points) IS NOT NULL THEN 1
END AS rank,
s.*
from (
SELECT t.alias, SUM(a.point) as total_points
FROM activity a
INNER JOIN feed f ON a.id = f.ActivityId
INNER JOIN team t ON f.TeamId = t.id
JOIN (SELECT #rank:=0, #totalval := 0) r
GROUP BY t.alias
ORDER BY total_points DESC
) as s;
Check it from here : https://dbfiddle.uk/7lKLu4Pw

Using the same logic as yours, You can do it as follows :
select #rownum:=#rownum+1 as 'Classement', s.*
from (
SELECT t.alias, SUM(a.point) as total_points
FROM activity a
INNER JOIN feed f ON a.id = f.ActivityId
INNER JOIN team t ON f.TeamId = t.id
JOIN (SELECT #rownum:=0) r
GROUP BY t.alias
ORDER BY total_points DESC
) as s;
Check it here : https://dbfiddle.uk/TEz3UT97
Its working on mysql and mariadb

Related

Retrieving a variable number of rows using a table join

This is an addition layer of complexity on another question I asked here: Using GROUP BY and ORDER BY in same MySQL query
Same table structure and problem, except this time imagine that the past_election table is now set up as...
| election_ID | Date | jurisdiction | Race | Seats |
|-------------|------------|----------------|---------------|-------|
| 1 | 2016-11-08 | federal | president | 1 |
| 2 | 2016-11-08 | state_district | state senator | 2 |
(last record has seats set as 2 instead of 1.)
I want to use the Seats number to grab different numbers of records, ordered by the number of votes, for each group. So in this case with the following additional tables...
candidates
| Candidate_ID | FirstName | LastName | MiddleName |
|--------------|-----------|----------|------------|
| 1 | Aladdin | Arabia | A. |
| 2 | Long | Silver | John |
| 3 | Thor | Odinson | NULL |
| 4 | Baba | Yaga | NULL |
| 5 | Robin | Hood | Locksley |
| 6 | Sherlock | Holmes | J. |
| 7 | King | Kong | Null |
past_elections-candidates
| ID | PastElection | Candidate | Votes |
|----|--------------|-----------|-------|
| 1 | 1 | 1 | 200 |
| 2 | 1 | 2 | 100 |
| 3 | 1 | 6 | 50 |
| 4 | 2 | 3 | 75 |
| 5 | 2 | 4 | 25 |
| 6 | 2 | 5 | 150 |
| 7 | 2 | 7 | 100 |
I would expect the following output:
| election_ID | FirstName | LastName | votes | percent |
|-------------|-----------|----------|-------|---------|
| 1 | Aladdin | Arabia | 200 | 0.5714 |
| 2 | Robin | Hood | 150 | 0.4286 |
| 2 | King | Kong | 100 | 0.2857 |
I've tried setting a variable and using that with a LIMIT statement but variables don't work in limits. I've also tried using ROW_NUMBER() (I'm not using MySQL 8.0 so this won't work but I'd be willing to upgrade if it did) or a related workaround like #row_number := IF ... and then filtering based on the row number but nothing has worked.
Last tried query:
SELECT pe.election_ID as elec,
pe.Seats as s,
pecs.row_num,
c.FirstName,
c.LastName,
pecs.max_votes AS votes,
pecs.max_votes / pecs.total_votes AS percent
FROM past_elections pe
JOIN `past_elections-candidates` pec ON pec.PastElection = pe.election_ID
JOIN (SELECT PastElection,
Candidate,
#row_num := IF(PastElection = #current_election, #current_election + 1, 1) as row_num,
MAX(Votes) AS max_votes,
SUM(Votes) AS total_votes,
#current_election := PastElection
FROM `past_elections-candidates`
GROUP BY PastElection) pecs ON pecs.PastElection = pec.PastElection AND pecs.row_num <= pe.Seats
JOIN candidates c ON c.Candidate_ID = pec.Candidate
Use MySQL 8 regardless ;)
Use ROW_NUMBER to order the past elections:
SELECT *, ROW_NUMBER() OVER(PARTITION BY pastelection ORDER BY votes DESC) as rown
FROM `past_elections-candidates`
Join this to past_elections as a subquery (this is just the bit you're stuck on with the "using pe.seats to vary the number of rows returned per election" and doesn't include the percent bits:
SELECT *
FROM
past_elections pe
INNER JOIN
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY pastelection ORDER BY votes DESC) as rown
FROM `past_elections-candidates`
) pecr
ON pecr.pastelection = pe.electionid AND
pecr.rown <= pe.seats
If you want to test things out on 8 before you upgrade, loads of the db fiddle sites support v8
ps; percent-y stuff can be done at the same time as the ROW_NUMBER with eg:
votes/SUM(votes) OVER(PARTITION BY past_election)
eg for election ID 1 that sum will be 200+100+50, giving 200/350 = ~57%
SELECT *, votes/SUM(votes) OVER(PARTITION BY past_election) as pcnt, ROW_NUMBER() OVER(PARTITION BY pastelection ORDER BY votes DESC) as rown
FROM `past_elections-candidates`
You need to calc it before filtering
I don't have the right fields listed but this is as close as I'll probably get tonight... I've gotten the rows I need but need to join the candidate table to get the name out...
Using Dense_Rank seems to work for this...
SELECT * FROM (
SELECT pec.PastElection,
c.FirstName,
c.LastName,
pec.Votes,
pecs.totalVotes,
pe.Seats as s,
DENSE_RANK() OVER(PARTITION BY PastElection ORDER BY Votes DESC) as rank_votes
FROM `past_elections-candidates` pec
JOIN (SELECT PastElection,
Max(Votes) as maxVotes,
Sum(Votes) as totalVotes
FROM `past_elections-candidates`
GROUP BY PastElection) pecs ON pecs.PastElection = pec.PastElection
JOIN `past_elections` pe ON pec.PastElection = pe.election_ID
JOIN candidates c ON c.Candidate_ID = pec.Candidate
) t WHERE rank_votes <= s;
This results in
| PastElection | FirstName | LastName | Votes | totalVotes | s | rank_votes |
|--------------|-----------|----------|-------|------------|---|------------|
| 1 | Aladdin | Arabia | 200 | 350 | 1 | 1 |
| 2 | Robin | Hood | 150 | 350 | 2 | 1 |
| 2 | King | Kong | 100 | 350 | 2 | 2 |
I guess it's just kind of messy having the rank_votes and s columns in the data, but that's honestly fine with me if it gets the results I need.

Join 3 Tables in a MySql Query

i have this 3 tables in a MySql Database.
users
+----+------+--------+------+
| Id | Name | Status | Role |
+----+------+--------+------+
| 1 | A | Aktiv | Op |
| 2 | B | Aktiv | Op |
| 3 | C | Aktiv | Op |
| 4 | D | Aktiv | Op |
+----+------+--------+------+
cnt
+----+------+------------+------+
| Id | Name | Date | Type |
+----+------+------------+------+
| 1 | A | 2017-11-09 | Web |
| 2 | B | 2017-11-09 | Web |
| 3 | C | 2017-11-09 | Web |
| 4 | C | 2017-11-09 | Inb |
| 5 | A | 2017-11-09 | Web |
+----+------+------------+------+
Lead
+----+------+------------------+------------+
| Id | Name | Date | Type |
+----+------+------------------+------------+
| 1 | A | 2017-11-09 00:24 | Imported |
| 2 | B | 2017-11-09 09:32 | Activation |
| 3 | B | 2017-11-09 10:56 | Activation |
| 4 | D | 2017-11-09 12:21 | Activation |
| 5 | D | 2017-11-10 12:22 | Activation |
+----+------+------------------+------------+
I'm trying to join them in a main table but with no success, the query i'm using is:
SELECT IFNULL(u.Name,'Total') as "Name",
Sum(IF(c.Type = 'Web',1,0)) as "Cnt Web",
Sum(IF(l.Type = 'Activation',1,0)) as "Lead Web"
FROM users u
LEFT JOIN cnt c ON u.Name = c.Name and c.Date = '2017-11-09'
LEFT JOIN lead l ON u.Name = l.Name and l.Date>= '2017-11-09' AND l.Date< '2017-11-10'
WHERE u.Status = 'Aktiv' AND u.Role = 'Op'
GROUP BY u.Name WITH ROLLUP
The result i need is a table like this:
+----+------+--------+---------+
| Id | Name | Cnt Web| Lead Web|
+----+------+------------------+
| 1 | A | 2 | 0 |
| 2 | B | 1 | 2 |
| 3 | C | 1 | 0 |
| 4 | D | 0 | 1 |
+----+------+------------------+
When i try to join the first table with the second or the first with the third, i get the correct result, but i can't get the needed result when i join them all.
Any answer is the most welcomed. Thank you in advance.
Here's a solution using correlated sub-queries
SELECT u.Id,
u.Name,
(SELECT COUNT(Name) FROM cnt WHERE Name = u.name AND type = 'Web' AND Date = '2017-11-09') AS cnt_web,
(SELECT COUNT(Name) FROM lead WHERE Name = u.name AND type = 'Activation' AND Date>= '2017-11-09' AND Date< '2017-11-10') AS cnt_lead
FROM users u
WHERE u.Status = 'Aktiv' AND u.Role = 'Op'

Incorrect update with inner join

I encountered a problem that I just can not solve.
For example, I have the table with rows, id, season, episode, order.
Data in the table looks like:
+--------+---------------+----------------+--------------+
| id | season | episode | order |
+--------+---------------+----------------+--------------+
| 153914 | 1 | 1 | NULL |
| 153915 | 1 | 3 | NULL |
| 153916 | 1 | 2 | NULL |
| 153919 | 1 | 3 | NULL |
| 153920 | 1 | 4 | NULL |
| 153921 | 1 | 3 | NULL |
+--------+---------------+----------------+--------------+
So, when I run SELECT query without UPDATE, row order is sorted absolutely correctly
SELECT id, season, episode, (#row:=#row+1) as order
FROM `shows`, (select #row:=0) as rc
WHERE `show_id`= 14670
ORDER BY CAST(season AS UNSIGNED) ASC, CAST(episode AS UNSIGNED) ASC
+--------+--------+---------+--------+
| id | season | episode | order |
+--------+--------+---------+--------+
| 153914 | 1 | 1 | 1 |
| 153916 | 1 | 2 | 2 |
| 153915 | 1 | 3 | 3 |
| 153919 | 1 | 3 | 4 |
| 153921 | 1 | 3 | 5 |
| 153920 | 1 | 4 | 6 |
+--------+--------+---------+--------+
But when I use the same query as the subquery of UPDATE statement it doesn't sort the same way and set different order values.
UPDATE `shows` f
JOIN
(
SELECT id, (#row:=#row+1) as rowOrder
FROM `shows` as Fl, (select #row:=0) as rc
WHERE Fl.`show_id` = 14670
ORDER BY Fl.season ASC, Fl.episode ASC
) t
ON t.id = f.id
SET f.order = t.rowOrder
mysql> SELECT id, season, episode, order FROM `shows` WHERE `show_id`=14670;
+--------+--------+---------+--------+
| id | season | episode | order |
+--------+--------+---------+--------+
| 153914 | 1 | 1 | 1 |
| 153915 | 1 | 3 | 2 |
| 153916 | 1 | 2 | 3 |
| 153919 | 1 | 3 | 4 |
| 153920 | 1 | 4 | 5 |
| 153921 | 1 | 3 | 6 |
+--------+--------+---------+--------+
Please, explain to me why it happens and how to solve it.
MySQL version:
>mysql --version
mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64) using EditLine wrapper
Hmmm. It would appear that the order by is not affecting the variable. I wonder if this has changed in recent versions of MySQL. It certainly used to work.
In any case, you can fix it by using a subquery:
UPDATE shows s JOIN
(SELECT id, (#row:=#row+1) as rowOrder
FROM (SELECT id, sea
FROM shows s2
WHERE s2.show_id = 14670
ORDER BY s2.season ASC, s2.episode ASC
) s2 CROSS JOIN
(SELECT #row := 0) as rc
) s3
ON s.id = s3.id
SET s.order = s3.rowOrder;

mysql: how to save ORDER BY after LEFT JOIN without reorder?

I've two table:
1) profiles
+----+---------+
| id | name |
+----+---------+
| 1 | WILLIAM |
| 2 | JOHN |
| 3 | ROBERT |
| 4 | MICHAEL |
| 5 | JAMES |
| 6 | DAVID |
| 7 | RICHARD |
| 8 | CHARLES |
| 9 | JOSEPH |
| 10 | THOMAS |
+----+---------+
2) request_for_friendship
+----+---------+-------+
| id | from_id | to_id |
+----+---------+-------+
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 1 | 8 |
| 5 | 4 | 1 |
| 6 | 9 | 1 |
+----+---------+-------+
I need to get all profiles with some sorting and join it with request_for_friendship
For example, get all users with some sorting:
mysql> SELECT *
-> FROM profiles
-> ORDER BY name ASC;
+----+---------+
| id | name |
+----+---------+
| 8 | CHARLES |
| 6 | DAVID |
| 5 | JAMES |
| 2 | JOHN |
| 9 | JOSEPH |
| 4 | MICHAEL |
| 7 | RICHARD |
| 3 | ROBERT |
| 10 | THOMAS |
| 1 | WILLIAM | <-- WILLIAM IS LAST!
+----+---------+
Everything looks good, sorting is present. After that I join with request_for_friendship and my sotring will breaks:
mysql> SELECT * FROM
-> (
-> SELECT *
-> FROM profiles
-> ORDER BY name ASC
-> ) as users
-> LEFT JOIN request_for_friendship
-> AS request_for_friendship_copy
-> ON
-> (
-> request_for_friendship_copy.from_id = 1
-> AND
-> request_for_friendship_copy.to_id = users.id
-> )
-> OR
-> (
-> request_for_friendship_copy.from_id = users.id
-> AND
-> request_for_friendship_copy.to_id = 1
-> );
+----+---------+------+---------+-------+
| id | name | id | from_id | to_id |
+----+---------+------+---------+-------+
| 2 | JOHN | 1 | 1 | 2 |
| 3 | ROBERT | 2 | 1 | 3 |
| 8 | CHARLES | 3 | 1 | 8 |
| 4 | MICHAEL | 5 | 4 | 1 |
| 9 | JOSEPH | 6 | 9 | 1 |
| 1 | WILLIAM | NULL | NULL | NULL | <-- WILLIAM IN THE MIDDLE!
| 5 | JAMES | NULL | NULL | NULL |
| 6 | DAVID | NULL | NULL | NULL |
| 7 | RICHARD | NULL | NULL | NULL |
| 10 | THOMAS | NULL | NULL | NULL |
+----+---------+------+---------+-------+
How to JOIN LEFT with original sorting saving?
I can't sort result after JOIN LEFT besause when I do ORDER BY before JOIN it takes ~0.02s in my db (~1 000 000 users) but when I do ORDER BY after JOIN it takes ~3.2s, it's very big time :(
Demo: rextester.com/DLLM29415
Demo: http://sqlfiddle.com/#!9/167792/1
In sqlfiddle order is saved! But how? MySQL 5.6 saved order?
(Explaining the loss of ORDER BY)
The SQL standard essentially says that a subquery is an unordered set of rows. This implies that the Optimizer is free to ignore the ORDER BY in the 'derived' table: FROM ( SELECT ... ORDER BY ). In "recent" versions of MySQL and MariaDB, such ORDER BYs are being dropped. There are other cases where ORDER BY is ignored.
In some situations (not sure about this one), adding a LIMIT 99999999 (big number) after the ORDER BY tricks the Optimizer into doing the ORDER BY. However, it is still free to ignore the "order" later.
A general rule for MySQL: Avoid subqueries. (There are cases where subqueries are faster, but not yours.)
A strong rule: You must have an ORDER BY on the outermost if you want the results to be sorted.
If you had added LIMIT 3 to the derived table in your first query, you would get only CHARLES, DAVID, JAMES, but not necessarily in that order. That is, you would need two ORDER BYs - one in the derived table, one at the very end.
SELECT *
FROM profiles p
LEFT
JOIN request_for_friendship r
ON (r.from_id = p.id AND r.to_id = 1)
OR (r.from_id = 1 AND r.to_id = p.id)
ORDER
BY name;
+----+---------+------+---------+-------+
| id | name | id | from_id | to_id |
+----+---------+------+---------+-------+
| 8 | CHARLES | 3 | 1 | 8 |
| 6 | DAVID | NULL | NULL | NULL |
| 5 | JAMES | NULL | NULL | NULL |
| 2 | JOHN | 1 | 1 | 2 |
| 9 | JOSEPH | 6 | 9 | 1 |
| 4 | MICHAEL | 5 | 4 | 1 |
| 7 | RICHARD | NULL | NULL | NULL |
| 3 | ROBERT | 2 | 1 | 3 |
| 10 | THOMAS | NULL | NULL | NULL |
| 1 | WILLIAM | NULL | NULL | NULL |
+----+---------+------+---------+-------+
10 rows in set (0.02 sec)
mysql>
Try this:
SELECT
a.name as `from_name`,
b.name as `to_name`,
c.from_id,
c.to_id
FROM profiles a
LEFT JOIN request_for_friendship c
ON a.id = c.from_id
LEFT JOIN profiles b
ON c.to_id = b.id
GROUP BY a.name,b.name
ORDER BY a.name,b.name;
Or, if you want one row per "from" name:
SELECT
a.name as `from_name`,
IFNULL(GROUP_CONCAT(b.name),'-none-') as `to_name`,
IFNULL(c.from_id,'-none-') as `from_id`,
IFNULL(GROUP_CONCAT(c.to_id),'-none-') as `to_id`
FROM profiles a
LEFT JOIN request_for_friendship c
ON a.id = c.from_id
LEFT JOIN profiles b
ON c.to_id = b.id
GROUP BY a.name
ORDER BY a.name,b.name
I know this question is a couple of years old, but I didn't find this possible solution already offered. This is the solution that worked best for me to keep the subquery results in the correct order.
Consider adding a "row_number" to your subquery. Then use ORDER BY on row_number.
This explains how to add the row_number:
select increment counter in mysql
In my case, I have an unknown number of possible rows in a hierarchical recursive query that I need to keep the order results of the subquery to remain the same in the outer query.
This is my query:
SELECT l.row_number, l.userid, l.child, p.id, p.username
FROM (
SELECT #rownum := #rownum + 1 AS row_number, u.parent AS userid, _id AS child
FROM (
SELECT #r AS _id, (SELECT #r := parent FROM new_clean WHERE userid = _id) AS parent
FROM (SELECT #r := ?) AS vars, new_clean h
WHERE #r <> 0
) u
CROSS JOIN (SELECT #rownum := 0) r
WHERE u.parent <> 0
) l
LEFT JOIN profile p ON p.userid = l.userid
ORDER BY row_number

Create view from multiple queries

I'm currently doing a sql script using the following tables in a database:
Menu table (contains the information about dishes):
+----------+--------------+--------+-------------+
| id_plato | nombre_plato | precio | tipo |
+----------+--------------+--------+-------------+
| 1 | peces | 100 | entrada |
| 2 | caca | 20 | rolls_fondo |
| 3 | plato1 | 200 | bajativo |
| 4 | plato2 | 200 | entrada |
| 5 | plato3 | 200 | entrada |
| 6 | plato4 | 200 | entrada |
| 7 | plato5 | 200 | entrada |
| 8 | plato6 | 200 | entrada |
| 9 | plato7 | 200 | entrada |
| 10 | plato8 | 200 | entrada |
| 11 | plato9 | 200 | entrada |
| 12 | plato10 | 200 | entrada |
| 13 | plato11 | 200 | entrada |
| 14 | plato1 | 200 | entrada |
+----------+--------------+--------+-------------+
Boleta table (contains the informatio of all sales):
+-----------+------+--------------+
| id_boleta | sexo | precio_final |
+-----------+------+--------------+
| 1 | m | 1 |
| 2 | f | 1 |
| 3 | f | 1 |
| 4 | m | 1 |
+-----------+------+--------------+
BoletaDetalle table (contains the information of each dish bought on a given sale):
+------------+-----------+----------+----------------+
| id_detalle | id_boleta | id_plato | precio_detalle |
+------------+-----------+----------+----------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 1 | 2 | 1990 |
| 4 | 2 | 1 | 5 |
| 5 | 3 | 4 | 1 |
| 6 | 4 | 2 | 1 |
| 7 | 5 | 4 | 1 |
| 8 | 4 | 2 | 1 |
+------------+-----------+----------+----------------+
Basically, this is a small program for a small restaurant and I have been asked to show a quick report trough an sql script that displays a view containing the favorite dish of a certain group of costumers. For example, based on costumer's gender as follows:
| Sex | Type |
+------------------+
| M | entrada |
| F | bajativo |
I'm having a lot of trouble trying to figure this out despite of it being an easy task.
This is what I have so far:
DROP VIEW IF EXISTS v1;
CREATE VIEW v1 (Tipo, CantidadMujer, CantidadHombre)
AS
SELECT m.tipo as Tipo, COUNT(bd.id_plato) as 'Cantidad Mujer', COUNT(bd2.id_plato) as 'Cantidad Hombre'
FROM Menu m
LEFT JOIN BoletaDetalle bd
INNER JOIN Boleta b
on (bd.id_boleta = b.id_boleta AND b.sexo = 'f')
on bd.id_plato = m.id_plato AND m.tipo = 'entrada'
LEFT JOIN BoletaDetalle bd2
INNER JOIN Boleta b2
on (bd2.id_boleta = b2.id_boleta AND b2.sexo = 'm')
on bd2.id_plato = m.id_plato AND m.tipo = 'entrada'
GROUP BY(m.tipo);
SELECT * FROM v1;
I was thinking of creating a view like the one above with the amount of dishes bought per each gender (on each dish type) and then create a second view (the final one) by getting the maximum value per category. I'm really lost here so any help would be appreciated.
Are you looking for something like this?
CREATE VIEW sexo_tipo_view AS
SELECT b.sexo, m.tipo, COUNT(d.id_plato) total
FROM boletadetalle d JOIN boleta b
ON d.id_boleta = b.id_boleta JOIN menu m
ON d.id_plato = m.id_plato
GROUP BY b.sexo, m.tipo
ORDER BY sexo, total DESC;
CREATE VIEW sexo_tipo_favorites_view AS
SELECT sexo, tipo
FROM sexo_tipo_view
GROUP BY sexo;
SELECT s.sexo, COALESCE(v.tipo, '-') tipo
FROM
(
SELECT 'f' sexo UNION ALL
SELECT 'm'
) s LEFT JOIN sexo_tipo_favorites_view v
ON s.sexo = v.sexo;
or without views
SELECT s.sexo, COALESCE(v.tipo, '-') tipo
FROM
(
SELECT 'f' sexo UNION ALL
SELECT 'm'
) s LEFT JOIN
(
SELECT sexo, tipo
FROM
(
SELECT b.sexo, m.tipo, COUNT(d.id_plato) total
FROM boletadetalle d JOIN boleta b
ON d.id_boleta = b.id_boleta JOIN menu m
ON d.id_plato = m.id_plato
GROUP BY b.sexo, m.tipo
ORDER BY sexo, total DESC
) a
GROUP BY sexo
) v
ON s.sexo = v.sexo;
Sample output (in both cases):
| SEXO | TIPO |
|------|-------------|
| f | entrada |
| m | rolls_fondo |
Here is SQLFiddle demo