Join several times - mysql

I've a table with fields id_osztaly, id_csoportositas and name (and some other fields but there aren't important).
I want create a query with the follow result: I want combine the name fields. I can't explain so I show an example:
the datas in the table (id_osztaly, id_csoportositas and name order):
1,1,Group1A
1,1,Group1B
1,2,Group2A
1,2,Group2B
I want the follow combine from name:
Group1A-Group2A
Group1A-Group2B
Group1B-Group2A
Group1B-Group2B
(similar the permutation). I can do this with a JOIN, it's ok. But when I three different value of id_csoportositas:
1,1,Group1A
1,1,Group1B
1,2,Group2A
1,2,Group2B
1,3,Group3A
1,3,Group3B
1,3,Group3C
I want:
Group1A-Group2A-Group3A
Group1A-Group2A-Group3B
Group1A-Group2A-Group3C
Group1A-Group2B-Group3A
Group1A-Group2B-Group3B
Group1A-Group2B-Group3C
Group1B-Group2A-Group3A
Group1B-Group2A-Group3B
Group1B-Group2A-Group3C
Group1B-Group2B-Group3A
Group1B-Group2B-Group3B
Group1B-Group2B-Group3C
Yes, it's double join. But I don't know how many different id_csoportositas exist in table. First blick I think I need same number of JOIN as the number of different id_csoportositas.
Is there any trick in (my)sql to do this or should I do it in PHP with a for-cycle?
EDIT maybe I wasn't clear. I know how can I JOIN same table two times or three times. If I've two different id_csoportositas I need only one JOIN. If I've three different id_csoportositas I need two JOIN - I can do this too. But I don't know how many different id_csoportositas exist so I don't know how many JOIN will need. The number of JOINs depends on number of different id_csoportositas and I don't know the number of id_csoportositas without a query.
And I want to group by id_osztaly and different id_osztaly has different id_csoportositas.
I hope it's clear now.

Won't something like this work:
SELECT * FROM
(
(SELECT * FROM table WHERE something = 1) a,
(SELECT * FROM table WHERE something = 2) b,
(SELECT * FROM table WHERE something = 3) c
)
You just select like this and it would provide all possible variations of the joins :)

Related

Subquery or join to get one string from the same two tables multiple times

Related to Join vs. sub-query but a different type of situation, and just trying to understand how this works.
I had to make a view where I get a bunch of employee codes from one table, and I have to get their names from a different table - the same two tables every time. I arranged my query like this:
SELECT
(SELECT name from emptable where empcod = code1) as emp1, code1,
(SELECT name from emptable where empcod = code2) as emp2, code2,
[repeat 6 times]
FROM codetable
It is more complicated than this, and more tables are joined, but this is the element I want to ask about. My boss says joining like so is better:
SELECT e1.name, c.code1, e2.name, c.code2, e3.name, code3 [etc]
FROM codetable c
INNER JOIN emptable e1 ON e1.empcod = c.code1
INNER JOIN emptable e2 ON e2.empcod = c.code2
INNER JOIN emptable e3 ON e3.empcod = c.code3
My reasoning, aside from not having to go search in the joins which table gets whose name and why, is the way I understand the join goes like this:
Take whole table A
Take whole table B
Combine all the data from both tables according to the 'ON' section of the join
select one single string from this complete combination of two whole tables from which I need no other data
I think it's obvious that this seems like it would take up a lot of resources. I understand the subquery as
Get one datum from table A (the employee code)
Match this one datum to every record from table B until you find a match
As soon as you get a match, bring back this one single datum from this other table (the employee's name)
Understanding that in the table of employees, the employee code is a primary key and cannot be duplicated, so every subquery can only ever give me one single string back.
It seems to me that comparing ONE number from one table to ONE number from another table and retrieving ONE string related to that number would be less resource-intensive than matching ALL of the data in two whole tables together in order to get this one string. But I figure I don't know what these databases are doing behind the scenes, and a lot of people seem to prefer joins. Can anyone explain this to me, if I'm understanding it wrong? The other posts I find here of similar situations tend to want more information from more tables, I'm not immediately finding anything about matching the same two tables six or seven times to retrieve one single string for every configuration.
Thanks in advance.
So as ScaisEdge explained, a join only gets executed once - and thus only spends time and resources once - no matter how many rows you have, whereas each of the six subselects get executed once for every row. If you have 100 rows, you're executing six joins once or you're executing 6 subselects 100 times.
It makes sense that this would be more resource-intensive, and I did not explain clearly enough that my case involves only one row at a time - in which case I guess the difference would be negligible anyway.

MySQL join two completely identical tables with WHERE

I have two of same tables with different names. The first one's name is "folders" and the second one is "folders_archive".
I like to INNER JOIN this two tables with thier full content by filtering it on a date. If I use two single query's, thats works fine, but the joined query has no result.
I like something like this:
SELECT *
FROM folders
INNER JOIN folders_archiv
ON folders_archiv.id= folders.id
WHERE folders_archiv.datum = '".$year."-".$month."-".$day."'
AND folders.datum = '".$year."-".$month."-".$day."';
I'm trying to connect these tables in several way, but something is wrong with my logic, please help to fix it.
Thanks.
You question is not very clear, by i think you need Union - gives you all records from two table without repeat(if repeat is acceptable use union all). For example:
select t1.* from (
SELECT column_names
FROM folders
UNION
SELECT column_names
FROM folders_archive) t1
WHERE t1.column_names = what_you_want;
Very vague question.
But try this:
SELECT *
FROM folders
INNER JOIN folders_archiv
ON folders_archiv.datum= folders.datum
WHERE folders_archiv.datum = '".$year."-".$month."-".$day."'

SQL Query Help on 3 Tables with a Many to Many relationship

I had an issue joining multiple tables to retrieve the data I needed. In order to accomplish the proper results I had to first create a view (shown below) called: vwinvgrossrev :
SELECT dbo.inv_item.inv_num, dbo.inv_item.co_line,
dbo.inv_hdr.co_num, dbo.inv_hdr.inv_date, dbo.inv_item.qty_invoiced,
dbo.inv_item.price
FROM dbo.inv_item INNER JOIN
dbo.inv_hdr ON dbo.inv_item.inv_num = dbo.inv_hdr.inv_num
and then I had to join the view on my final table in order to create a proper summation of the values that I wanted
select sum(vwinvgrossrev.qty_invoiced*vwinvgrossrev.price)
from vwinvgrossrev,coitem
WHERE vwinvgrossrev.co_num=coitem.co_num
AND coitem.Uf_Erne='Y'
AND vwinvgrossrev.co_line=coitem.co_line
AND DATEPART(mm,vwinvgrossrev.inv_date) = DATEPART(mm,Getdate())
AND YEAR(vwinvgrossrev.inv_date) = YEAR(Getdate())
My question is this. Is there anyway to do this in a single query. The problem is all 3 tables have a many to many relationship with one another and always returns the wrong value when joining all 3 tables.
If your current query (using the view) gives you what you are looking for then I believe that this query will give you the same thing in a single query:
SELECT sum(inv_item.qty_invoiced*inv_item.price)
FROM inv_item
JOIN inv_hdr ON dbo.inv_item.inv_num = dbo.inv_hdr.inv_num
JOIN coitem ON (inv_hdr.co_num=coitem.co_num
AND inv_item.co_line=coitem.co_line)
WHERE coitem.Uf_Erne='Y'
AND vwinvgrossrev.co_line=coitem.co_line
AND DATEPART(mm,inv_hdr.inv_date) = DATEPART(mm,Getdate())
AND YEAR(inv_hdr.inv_date) = YEAR(Getdate())
However, I'll be surprised if that is what you are looking for.
I am assuming that you don't actually have a many-to-many between all 3. I am assuming that inv_hdr has a unique inv_num and inv_item has many of those. Similarly I am assuming that co_num is unique within inv_hdr but has multiple occurrences within coitem. These are not many-to-many but rather 1-to-many relationships. Since SELECT multiplies rows I think you are going to be summing way more than you want.
Why do you want to include coitem at all if you are just interested in inv_item.qty_invoiced and inv_item.price? Is it just to limit on the Uf_Erne column? Is coitem always going to have either 1 or 0 records for that co_num and co_line with Uf_Erne='Y'?
In sum, I've reproduced your query in a single query without a view, but I think you may need to think through whether this is really what you want.
You need to refine your database schema to normalise out the many-to-many relationships. That is a given and is standard practice regardless of your current problem. The fact that it will simplify your current problem is the reason why. There are many tutorials/blog/etc out there to show you how to do this with join tables so I am not going into it here.

Merging two tables

I have two tables with the following descriptions:
record(record_id,min_index,max_index)
points(point_id,point_name,val1,val2,rank), point_id being on auto-increment
The min_index,max_index from record table points to the point_ids in the point table.
i.e. for a particular record, the respective points are >=min_index and <=max_index.
I need to merge these two tables such that, the final table resembles something like this
points(point_id,record_id,point_name,val1,val2,rank)
I know this is against the normalisation criteria, but this seems to work very well with the problem i have. I'm not sure on how to go about merging these two tables.
Just join the tables using MySQL's BETWEEN ... AND ... operator to specify your join criterion:
SELECT points.point_id,
record.record_id,
points.point_name,
points.val1,
points.val2,
points.rank
FROM points JOIN record ON
points.point_id BETWEEN record.min_index AND record.max_index
SELECT a.point_id,
b.record_id,
a.point_name,
a.val1,
a.val2,
a.rank
from points a , record b
where ((point_id>=min_index)and (point_id<=max_index))

Select Distinct Field on Join

I am joining two large tables in MySQL based on a unique identifier they both share. Because there are a large number of fields, I do not want to list out all fields after SELECT. Instead I want to select all fields, but I do not want recurring fields (the shared unique identifier in this case) to be repeated.
With this example query:
SELECT *
FROM Gr3_PracMath_Jan11_D1 as a, student_list_011811 as b
WHERE a.StudentID = b.StudentID
The field StudentID is repeated. Is there a way to prevent this?
I believe that if you do an explicit join with the USING keyword, you won't get a duplicate.
SELECT *
FROM Gr3_PracMath_Jan11_D1
LEFT JOIN student_list_011811
USING (StudentID)
I don't think there is. You might cut your work by listing only half the fields:
SELECT a.*, b.Field1, b.Field2...
It is bad practice to not list out all of the columns, even if there are a lot of them. Just bite the bullet and write them out.