Mysql, repeat row by the max count of details - mysql

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 |
|-----------|----------------|----------------|

Related

Combine two tables into one table without using join and without the result creating cartesian product

How do I make a table of results of two different ratings without creating a cartesian product. diffrating and hostrating are two different types of user ratings. The users are rating the spots which are are labeled with spotId. userdiffrating and userhostrating are linking the users ratings to the correct spots. I am trying to get all the ratings for a specific spot in a table. Sample data and the expected output are bellow.
Table contents:
userdiffrating:
-------------------------------
| RatingId | userId | spotId |
-------------------------------
| 1 | 1 | 1 |
-------------------------------
| 2 | 2 | 1 |
-------------------------------
| 3 | 1 | 2 |
-------------------------------
diffrating:
----------------------
| RatingId | userId |
----------------------
| 1 | 5 |
----------------------
| 2 | 2 |
----------------------
| 3 | 4 |
----------------------
userhostrating:
-------------------------------
| RatingId | userId | spotId |
-------------------------------
| 1 | 1 | 1 |
-------------------------------
| 2 | 2 | 1 |
-------------------------------
| 3 | 1 | 1 |
-------------------------------
hostrating:
----------------------
| RatingId | userId |
----------------------
| 1 | 1 |
----------------------
| 2 | 3 |
----------------------
| 3 | 4 |
----------------------
This is what I originally tried but this creates a cartesian product:
SELECT D.rating diffrating, H.rating hostrating FROM diffrating D
JOIN userdiffrating UD ON D.ratingId = UD.ratingId
JOIN userhostrating UH ON UD.spotId = UH.spotId
JOIN hostrating H ON UH.ratingId = H.ratingId WHERE UD.spotId = 1
Result from first query (cartesian product):
-------------------------
| diffrating| hostrating|
-------------------------
| 5 | 1 |
-------------------------
| 5 | 3 |
-------------------------
| 5 | 4 |
-------------------------
| 2 | 1 |
-------------------------
| 2 | 3 |
-------------------------
| 2 | 4 |
-------------------------
I tried this next query but I cant use a select statement that has more than one row as a subquery:
SELECT D.rating AS diffrating, H.rating AS hostrating
FROM diffrating D, hostrating H
WHERE D.ratingId = (SELECT ratingId FROM userdiffrating UD WHERE UD.spotId = 1)
AND H.ratingId = (SELECT ratingId FROM userhostrating UH WHERE UH.spotId = 1)
This is the expected result (all diff and host ratings for spotId = 1):
-------------------------
| diffrating| hostrating|
-------------------------
| 5 | 1 |
-------------------------
| 2 | 3 |
-------------------------
| NULL | 4 |
-------------------------
This is the database:
Is this possible and how would this be done?
Thanks
I think what you are trying to code is this
SELECT dr.rating diffratingval, hr.rating hostratingval
FROM diffrating dr
JOIN userdiffrating udr
ON dr.ratingid = udr.ratingid
JOIN userhostrating uhr
ON udr.spotid = uhr.spotid
JOIN hostrating hr
ON uhr.ratingid = hr.ratingid
AND dr.ratingid = hr.ratingid
WHERE udr.spotid = 60;

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;

INNER JOIN shows only first row in table

I have the following data in my database:
scu_banks:
---------------------------------
| id | type | name |
|-------------------------------|
| 1 | 1 | One |
| 2 | 1 | Two |
| 3 | 2 | Three |
| 4 | 3 | Four |
---------------------------------
scu_statement:
---------------------------------
| id | code | mutation |
|-----------------------------------|
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 2 | 500 |
| 4 | 1 | 500 |
-------------------------------------
What I want to do is I want to select all the rows in table scu_banks and show the total sum of mutations. The data should be represented like:
--------------------------------------------------------------
| scu_banks.type | scu_banks.name | total | scu_banks.id |
--------------------------------------------------------------
| 1 | One | € 800.00 | 1 |
| 1 | Two | € 500.00 | 2 |
| 2 | Three | € 0.00 | 3 |
| 3 | Four | € 0.00 | 4 |
--------------------------------------------------------------
When I run my sql statement I get the following data:
---------------------------------------------------------------
| scu_banks.type | scu_banks.name | total | scu_banks.id |
--------------------------------------------------------------
| 1 | One | € 1300.00 | 1 |
---------------------------------------------------------------
The data I get in this case is not correct. € 1300.00 it the total of all the mutations in table scu_statement. The statement also dont shows the other rows in the database.
Does someone know what is wrong with my sql statement?
Here is my sql statement:
SELECT scu_banks.type,
scu_banks.name,
CONCAT('€ ', FORMAT(IFNULL(SUM(scu_statement.mutations), 0),2)) AS total,
scu_banks.id
FROM scu_banks
INNER JOIN scu_statement
ON scu_banks.id = scu_statement.code
Do the aggregation in a subquery and left join it to the banks.
SELECT b.type "scu_banks.type",
b.name "scu_banks.name",
concat('€ ', format(coalesce(x.mutation, 0), 2)) "total",
b.id "scu_banks.id"
FROM scu_banks b
LEFT JOIN (SELECT s.code,
sum(s.mutation) mutation
FROM scu_statement s
GROUP BY s.code) x
ON x.code = b.id;

SQL: exact row match given certain elements

this is my first time posting here. I don't seem to find the answer to my problem.
So... I'm arranging a DB for a school project, a cookbook that only shows recipes that can be made with existing elements from the "shelf".
These ingredients have to have an exact ingredients match.
user:
+---------------+------+----------+----------+
| email | name | lastname | password |
+---------------+------+----------+----------+
| pal#mail.com | John | Potato | password |
| they#mail.com | Mary | Carrot | password |
+---------------+------+----------+----------+
shelf:
+---------+------------+---------------+
| shelfID | ingredient | user |
+---------+------------+---------------+
| 1 | 1 | pal#mail.com |
| 2 | 2 | pal#mail.com |
| 3 | 3 | pal#mail.com |
| 4 | 4 | pal#mail.com |
| 5 | 10 | they#mail.com |
| 6 | 12 | they#mail.com |
+---------+------------+---------------+
This is my recipe_ingredient relationship table
recipe_ingredient:
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 2 |
| 3 | 3 |
| 3 | 15 |
+--------+------------+
I've tried this query:
SELECT
rec_ing.recipe, shf.ingredient, shf.user
FROM
recipes_ingredients AS rec_ing
INNER JOIN
shelf AS shf ON rec_ing.ingredient = shf.ingredient
INNER JOIN
users AS usr ON shf.user = usr.email
WHERE
usr.email = 'pal#mail.com'
that returns this table:
+--------+------------+--------------+
| recipe | ingredient | user |
+--------+------------+--------------+
| 1 | 1 | pal#mail.com |
| 1 | 2 | pal#mail.com |
| 1 | 4 | pal#mail.com |
| 2 | 1 | pal#mail.com |
| 2 | 2 | pal#mail.com |
| 2 | 3 | pal#mail.com |
| 2 | 4 | pal#mail.com |
| 3 | 2 | pal#mail.com |
| 3 | 3 | pal#mail.com |
+--------+------------+--------------+
Although it's true that the Recipe 1 contains ingredients from my shelf, it's also missing Ingredient 10
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| ... | ... |
+--------+------------+
I'm trying to only get this kind of result set.
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
+--------+------------+
Because Recipe 2 contains all elements from my shelf
I have been going around all day with this problem ... What could be missing?
This is a bit tricky, because you need to aggregate your current query by recipe, but you also need the original query to get back the full records. Sadly, MySQL does not support common table exprrssions or other features which could give us a less verbose query.
SELECT
rec_ing.recipe,
shf.ingredient,
shf.user
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
INNER JOIN users AS usr
ON shf.user = usr.email
INNER JOIN
(
SELECT rec_ing.recipe
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
LEFT JOIN users AS usr
ON shf.user = usr.email
WHERE
usr.email = 'pal#mail.com'
GROUP BY rec_ing.recipe
HAVING COUNT(usr.email) = COUNT(*)
) t
ON rec_ing.recipe = t.recipe
WHERE
usr.email = 'pal#mail.com'
The basic strategy here is to just do one additional join to a subquery which identifies all recipes where every ingredient belongs to a given user. The critical part is the following:
HAVING COUNT(usr.email) = COUNT(*)
This checks that the total number of rows for a given recipe matches the number of rows which have been assigned to a given user.

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?