I have a question about getting data from a table with multiple joins.
Table 1 holds the information (name and amount) and table 2 contains the combinations.
A row in table 2 contains the id's which correspond to the ID's from table 1.
I try to get the information out of table 1 based on the corresponding id's in table 2.
Table1
Id | Name | Amount
--------------------
4 | Test 1 | 50
5 | Test 2 | 60
6 | Test 3 | 70
7 | Test 4 | 80
Table2
id | PriceId | MaterialId | ServiceId
-------------------------------------
1 | 4 | 5 | 6
2 | 4 | 5 | 7
Query
To get an idea what I try to reach:
SELECT * FROM Table1 a
LEFT JOIN Table2 b ON a.Id = b.PriceId
LEFT JOIN Table2 c ON a.Id = c.MaterialId
LEFT JOIN Table2 d ON a.Id = d.ServiceId
GROUP BY a.Id
So I try to get the name and amount from table 1 corresponding with the Id's in table 2, Thus:
When I select everything from Table 2 with ID 1 then I try to get the following:
Table 2 with ID 1: PriceId = 4, MaterialId = 6, ServiceId = 6
Table 1: Test 1, Test 2, Test 3
Because PriceId 4 is corresponding with Test 1, and MaterialID 6 is corresponding with Test 2 etc etc.
Hopefully above is clearly. Any help is appreciated!
It seems you are approaching it from the wrong direction. What you really want is:
SELECT t2.PriceId AS PriceId,
t2.ServiceId AS ServiceId, t1p.Name AS PriceName,
t1m.Name AS MaterialName, t1s.Name AS ServiceName
FROM Table2 t2
LEFT JOIN Table1 t1p ON t2.PriceId = t1p.Id
LEFT JOIN Table1 t1m ON t2.MaterialId = t1m.Id
LEFT JOIN Table1 t1s ON t2.ServiceId = t1s.Id
See this fiddle.
Yes you can use that way ...
See my example :
select * from movies
inner join relationship as r1 on movies.id=r1.movie_id
inner join relationship as r2 on movies.id=r2.movie_id
where r1.Taxonomy_id ="xyz"
and r2.Taxonomy_id="abc"
GROUP BY movies.id
This will work for you. I had done this in one of my project
Related
I have a dataset of logged in users on a certain date
__ds__|__user_id__
1 | 1
1 | 2
2 | 2
2 | 3
3 | 3
3 | 1
3 | 2
i want to perform intersection on user_id over two consecutive dates, to have users who logged in today as well as previous day, so my final out put will be:
__ds__|__user_id__
2 | 2
3 | 3
3 | 2
I have wrote a query as:
select distinct t1.ds,t1.user_id
from user_table t1
where t1.user_id in(
select distinct user_id
from user_table
where ds = t1.ds-1
)
I applied distinct two time, which took too long time to run on big dataset. Is there more optimized way?
SELECT t1.ds, user_id
FROM test t1
JOIN test t2 USING (user_id)
WHERE t1.ds = t2.ds + 1
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=57c5c3ba48ef2547843882de3a47ca4b
I think it can be like this
select t2.ds,t2.user_id
from user_table t1
join user_table t2 on t1.user_id=t2.user_id and t2.ds=t1.ds+1
is right or not?
I have 2 tables, for example:
table A have data:
id | name
-----------
1 | nik
table B have fields:
id | id_a ( relation 1 to many to table A ) | name
---------------------------
3 | 1 | mark
4 | 1 | den
When i try to make sql request to each table i got only one line
# SQL from table A
SELECT * FROM A
WHERE A.id=1
# result is one line - 1 | nik
SQL from table B
SELECT min(B.id) FROM B WHERE B.id_a = 1
# also return 1 line - 3 | 1 | mark
But when i try to execute sql-request with LEFT JOIN i got 2 lines
SELECT count(*) FROM A
LEFT JOIN B ON B.id = ( SELECT min(B.id) FROM B WHERE B.id_a = A.id )
WHERE A.id=1
#will return - 2
I am confusing and can`t understand how it possible and how mysql works as this case.
Sorry guys.
Solution is use table aliases.
SELECT count(*) FROM A
LEFT JOIN B ON B.id = ( SELECT min(b1.id) FROM B as b1 WHERE b1.id_a = A.id )
WHERE A.id=1
In subquery add table alias B as b1 and all works fine
I have two column one column associated with another...
Table:base_data
id |---name----|-----des
1 | some name1 | The description1
2 | some name2 | The description2
Table: photos
id |---p_id----|-----photo
1 | 1 | img1s.jpg
2 | 1 | img1w.jpg
3 | 2 | img2.jpg
4 | 2 | img14.jpg
5 | 2 | img15.jpg
I want to select all data from table 1(base_data) and one row from associated row from photos: table how can I do that ????
I don't want to select by greatest n per group I want to select all data from the first table and only one row of the second table which matches with the first table row id, just first match not other.
The Result I want...
id |---name----|---des----|---p_id----|---photo----|
1 | some name |the des..1| 1 | img1s.jpg|
2 | some name |the des..2| 2 | img2.jpg|
I suppose you want to associate base_data with the first photo taken, which should be the one with the lowest photos.id. In MySQL, you could write this as follows: Create an intermediate query which gives - for any p_id - the corresponding record with the lowest id. Then, left join base_data with this intermediate query result. Hope there are not to many typos in it :-) :
select b.id, p2.photo
from base_data b left join
(select p.photo, p.p_id, min(id) from photos p group by p.p_id) p2 on b.id = p2.p_id
If you want the alphanumerically lowest photo name, in MySQL you can do this:
select
t1.*,
t2.photo
from
base_data as t1
left join (
select
p_id,
min(photo) as photo
from
photos
group by
p_id
) as t2 on t2.p_id = t1.id;
I don't exactly know how to word this question correctly, so I'll start with the data because I think it will make more sense that way.
Starting with these two tables:
Table 1:
user_id | equipment_id
------ | ------
1 | 2
1 | 3
1 | 6
2 | 2
2 | 6
Table 2:
equipment_id | exercise_id
------ | ------
2 | 1
3 | 2
6 | 2
I would like to create this third table:
Table 3:
user_id | exercise_id
------ | ------
1 | 1
1 | 2
2 | 1
It seems like a simple INNER JOIN to get the data, but I'm running into trouble with the second row. I only want that row to show up if user_id 1 has both pieces of equipment listed in Table 2. If either piece of equipment is missing, I don't want the data inserted as shown by user_id 2. I also want to make sure I don't get two instances of user_id 1 for each piece of equipment.
This is the code I have so far:
INSERT INTO Table3 (user_id, exercise_id)
SELECT user_id, exercise_id
FROM Table1
INNER JOIN Table2
ON Table2.equipment_id = Table1.equipment_id
The result I get is this with the rows that need to be removed indicated:
Table 3:
user_id | exercise_id
------ | ------
1 | 1
1 | 2
1 | 2 <--- duplicate of row above
2 | 1
2 | 2 <--- user 2 doesn't have equipment 3, so shouldn't be included
Any help on limiting the results would be greatly appreciated. Thank you!
If I understand correctly, you want to retrieve all the exercises for a user where all the equipment required for that exercise is "available" to the user. I've put some code over at rextester.com/AYRE74108. The important part of that looks like this:
select distinct
t1.user_id,
t2.exercise_id
from
table_1 t1
JOIN table_2 t2 ON
t1.equipment_id = t2.equipment_id
where
not exists
(select 1
from
table_2 t2b
where
t2b.exercise_id = t2.exercise_id
AND not exists (select 1
from
table_1 t1b
where
t2b.equipment_id = t1b.equipment_id
AND t1.user_id = t1b.user_id)
)
To explain the logic: I begin with the standard join and distinct. But then I require that there NOT EXIST any piece of equipment required for the exercise such that that user/equipment combination does NOT EXIST. This is equivalent to saying the user has to have "available" (listed in table 1) all the equipment required for the exercise.
Or schematically: "ALL X are Y" === "NO X is such that Not Y".
I feel that the last row of your output should not be 2 | 2 but 1 | 2.
Also using distinct will ensure that there will be no duplicate rows.
SELECT DISTINCT user_id, exercise_id
FROM Table1
INNER JOIN Table2
ON Table2.equipment_id = Table1.equipment_id
Edit - The mistake in the question threw me off. This should work.
SELECT user_id, table2.exercise_id , sum(table2.equipment_id), sum(b.equipment_id)
FROM Table1
INNER JOIN Table2
ON Table2.equipment_id = Table1.equipment_id
inner join table2 as b
on table2.exercise_id = b.exercise_id
group by user_id, table2.exercise_id
having sum(table2.equipment_id)= sum(b.equipment_id)
Database: mysql > ver 5.0
table 1: type_id (int), type
table 2: name_id, name, is_same_as = table2.name_id or NULL
table 3: id, table2.name_id, table1.type_id, value (float)
I want to sum values, and count values in table 3 where table2.name_id are same and also include the values of id where is_same_is=name_id. I want to select all data in table3 for all values in table2.
Apologize if my question is not very clear, and if it has already been answered but I am unable to find a relevant answer. Or dont exactly know what to look for.
[data]. table1
id | type
=========
1 | test1
2 | test2
[data].table2
name_id | name | is_same_as
==============================
1 | tb_1 | NULL
2 | tb_2 | 1
3 | tb_3 | NULL
4 | tb_4 | 1
[data].table3
id | name_id | type_id | value
======================================
1 | 1 | 1 | 1.5
2 | 2 | 1 | 0.5
3 | 2 | 2 | 1.0
output:
name_id| type_id|SUM(value)
=======================================================
1 | 1 |2.0 < because in table2, is_same_as = 1
2 | 2 |1.0
I think the following does what you want:
select coalesce(t2.is_same_as, t2.name_id) as name_id, t3.type_id, sum(value)
from table_3 t3 join
table_2 t2
on t3.name_id = t2.name_id
group by coalesce(t2.is_same_as, t2.name_id), t3.type_id
order by 1, 2
It joins the table on name_id. However, it then uses the is_same_as column, if present, or the name_id if not, for summarizing the data.
This might be what you are looking for: (I haven't tested it in MySQL, so there may be a typo)
with combined_names_tab (name_id, name_id_ref) as
(
select name_id, name_id from table2
union select t2a.name_id, t2b.name_id
from table2 t2a
join table2 t2b
on (t2a.name_id = t2b.is_same_as)
)
select cnt.name_id, t3.type_id, sum(t3.value) sum_val
from combined_names_tab cnt
join table3 t3
on ( cnt.name_id_ref = t3.name_id )
group by cnt.name_id, t3.type_id
having sum(t3.value) / count(t3.value) >= 3
Here's what the query does:
First, it creates 'combined_names_tab' which is a join of all the table2 rows that you want to GROUP BY using the "is_same_as" column to make that determination. I make sure to include the "parent" row by doing a UNION.
Second, once you have those rows above, it's a simply join to table3 with a GROUP BY and a SUM.
Note: table1 was unnecessary (I believe).
Let me know if this works!
john...