0

I have a more or less complex MySQL select query which is basically a select from a join of two complex tables:

 SELECT * 
  FROM 
     ( SELECT ProblemID
            , 10*POWER(COUNT(ProblemID), 2) AS TagsSignifikanz 
         FROM 
            ( SELECT ProblemID 
                FROM Problemtag 
               WHERE Tagtext = "Francois" 
               UNION 
                 ALL 
              SELECT ProblemID 
                FROM Problemtag 
               WHERE Tagtext = "Hollande"
            ) AS TagsSignifikanzTable 
        GROUP 
           BY ProblemID
     ) 
  JOIN 
     ( SELECT ProblemID
            , SUM(Einzelsignifikanz) AS Titelsignifikanz 
         FROM 
            ( SELECT ProblemID
                   , 1 AS Einzelsignifikanz 
                FROM Problem 
               WHERE Titel LIKE "%Francois%" 
               UNION 
                 ALL 
              SELECT ProblemID
                   , 1 AS Einzelsignifikanz 
                FROM Problem 
               WHERE Titel 
                LIKE "%Hollande%" 
               UNION 
                 ALL 
              SELECT ProblemID
                   , 4 AS Einzelsignifikanz 
                FROM Problem 
               WHERE Titel LIKE "%Francois Hollande%"
            ) AS TitelSignifikanzTable 
        GROUP 
           BY ProblemID
      ) AS TagsUndTitelSignifikanzTable 
     ON TagsSignifikanzQuery.ProblemID = TitelsignifikanzQuery.ProblemID;

I have been trying around for a while, but just can't figure out where I should insert a derived table's name. Who can help me out? Thanks in advance!

EDIT - The solution, by help of BK435 and Drew: (see line 7 and last 2 lines)

SELECT * FROM (
    SELECT ProblemID, 10*POWER(COUNT(ProblemID), 2) AS TagsSignifikanz FROM (
        SELECT ProblemID FROM Problemtag WHERE Tagtext = "Francois" 
            UNION ALL 
        SELECT ProblemID FROM Problemtag WHERE Tagtext = "Hollande"
    ) AS TagsSignifikanzTable GROUP BY ProblemID
) As Alias1
JOIN (
    SELECT ProblemID, SUM(Einzelsignifikanz) AS Titelsignifikanz FROM (
        SELECT ProblemID, 1 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Francois%" 
            UNION ALL 
        SELECT ProblemID, 1 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Hollande%" 
            UNION ALL 
        SELECT ProblemID, 4 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Francois Hollande%"
    ) AS TitelSignifikanzTable GROUP BY ProblemID
) AS Alias2 
ON Alias1.ProblemID = Alias2.ProblemID;
  • Well, I can only see one place where an alias is missing. Can't you? How about if we adjust the formatting... – Strawberry Aug 25 '15 at 22:52
  • I gotta say your re-formatting does nothing but confuse me, but I appreciate your implying that I'm stupid since I'm unable to see where it is missing – Peter Möhrenbart Aug 25 '15 at 23:12
  • @PeterMöhrenbart Strawberry was just trying to get you to see the error yourself...the reformatting helps...If you look after every closing `)` you have a `alias` except right before your `Join`...Which is what I answered below... – BK435 Aug 25 '15 at 23:32

2 Answers2

1

You should put an alias before the join since you aliased the inner select but not the outer select...

SELECT * FROM (
    SELECT ProblemID, 10*POWER(COUNT(ProblemID), 2) AS TagsSignifikanz FROM (
        SELECT ProblemID FROM Problemtag WHERE Tagtext = "Francois" 
            UNION ALL 
        SELECT ProblemID FROM Problemtag WHERE Tagtext = "Hollande"
    ) AS TagsSignifikanzTable GROUP BY ProblemID
) As Alias1
JOIN (
    SELECT ProblemID, SUM(Einzelsignifikanz) AS Titelsignifikanz FROM (
        SELECT ProblemID, 1 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Francois%" 
            UNION ALL 
        SELECT ProblemID, 1 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Hollande%" 
            UNION ALL 
        SELECT ProblemID, 4 AS Einzelsignifikanz FROM Problem WHERE Titel LIKE "%Francois Hollande%"
    ) AS TitelSignifikanzTable GROUP BY ProblemID
) 
AS TagsUndTitelSignifikanzTable ON TagsSignifikanzQuery.ProblemID = TitelsignifikanzQuery.ProblemID;
BK435
  • 3,076
  • 3
  • 19
  • 27
1

Consider this first (based on your comment to @BK435 that you deleted):

create table t1
(   id int auto_increment primary key,
    stuff1 varchar(100) not null,
    stuff2 varchar(100) not null
);
insert t1 (stuff1,stuff2) values ('111.1','111.2'),('111.3','111.4'),('111.5','111.6');

create table t2
(   id int auto_increment primary key,
    stuff1 varchar(100) not null,
    stuff2 varchar(100) not null
);
insert t2 (stuff1,stuff2) values ('222.1','222.2'),('222.3','222.4'),('222.5','222.6');

select * 
from t1 
join t2 
on t2.id=t1.id;
+----+--------+--------+----+--------+--------+
| id | stuff1 | stuff2 | id | stuff1 | stuff2 |
+----+--------+--------+----+--------+--------+
|  1 | 111.1  | 111.2  |  1 | 222.1  | 222.2  |
|  2 | 111.3  | 111.4  |  2 | 222.3  | 222.4  |
|  3 | 111.5  | 111.6  |  3 | 222.5  | 222.6  |
+----+--------+--------+----+--------+--------+

What happens with select * is that it grabs it all from the join on the two tables. It doesn't matter if it is real tables or derived tables with an Alias.

I also had the same column names in both tables to show the problem of not doing column aliases. The Below would fix that:

select t1.id,
t1.stuff1 as 1stuff1,t1.stuff2 as 1stuff2,t2.stuff1 as 2stuff1,t2.stuff2 as 2stuff2 
from t1 
join t2 
on t2.id=t1.id;

+----+---------+---------+---------+---------+
| id | 1stuff1 | 1stuff2 | 2stuff1 | 2stuff2 |
+----+---------+---------+---------+---------+
|  1 | 111.1   | 111.2   | 222.1   | 222.2   |
|  2 | 111.3   | 111.4   | 222.3   | 222.4   |
|  3 | 111.5   | 111.6   | 222.5   | 222.6   |
+----+---------+---------+---------+---------+

Now back to what BK435 did. It gives the first derived table an Alias, so you get by that error, and it enlightens us with the error that TagsSignifikanzQuery comes out of left field, unknown, and causes an error there.

So let's say BK runs this first with blank tables resulting:

create table problemtag
(   problemid int not null,
    tagtext varchar(100) not null
);

create table problem
(   problemid int not null,
    Einzelsignifikanz int not null,
    titel varchar(100) not null
);

Then runs his query. This is the error:

Error Code: 1054. Unknown column 'TagsSignifikanzQuery.ProblemID' in 'on clause'

So, when you join a,b,c,d etc (either real or derived table), it banks on the on clause to bring in the one you are working into the fold as having some relation to a (real or derived) table that is already in the join fold, if you will. But TagsSignifikanzQuery isn't. It is like someone threw Greek into the end of an English sentence. And the db engine is like 'huh?'

Edit (to illustrate your last error in Pink/Peach above)

create table t1
(   id int auto_increment primary key,
    stuff1 varchar(50) not null
);
insert t1 (stuff1) values ('111.1'),('111.2'),('111.3');

create table t2
(   id int auto_increment primary key,
    stuff2 varchar(50) not null
);
insert t2 (stuff2) values ('222.1'),('222.2'),('222.3');

create table t3
(   id int auto_increment primary key,
    stuff3 varchar(50) not null
);
insert t3 (stuff3) values ('333.1'),('333.2'),('333.3');

A1: an explicit Join

select t1.id,t1.stuff1,t2.stuff2 
from t1 
join t2 
on t2.id=t1.id;
+----+--------+--------+
| id | stuff1 | stuff2 |
+----+--------+--------+
|  1 | 111.1  | 222.1  |
|  2 | 111.2  | 222.2  |
|  3 | 111.3  | 222.3  |
+----+--------+--------+

A2: an error just like yours (Error: 1054)

select t1.id,t1.stuff1,t2.stuff2 
from t1 
join t2 
on t3.id=t1.id;
+----+--------+--------+
| id | stuff1 | stuff2 |
+----+--------+--------+
|  1 | 111.1  | 222.1  |
|  2 | 111.2  | 222.2  |
|  3 | 111.3  | 222.3  |
+----+--------+--------+

ERROR 1054 (42S22): Unknown column 't3.id' in 'on clause'

Why is my and your error the same? Because in my case, the select/join has no clue what I am talking about with t3, as the only thing it has been introduced to is t1 and t2 and I have not even completed the on clause for t2 yet. And I am referencing t3 (which exists as a table).

You may very well have a TagsSignifikanzQuery table. But it is just like my t3 in the join context. That is, the db engine has not been fed it correctly. You need to finish off the on clause bringing in t2. Then, continue with your join on TagsSignifikanzQuery if you have to.

But it errors out as written.

Edit2:


In what you wrote in comments:

... in the query "SELECT * FROM Table1 JOIN Table2" there is no AS clause needed although I would say you select data from a joined table which was not there before, i. e. a derived table. But the MySQL error goes "a derived table always needs an alias" or so, but it doesn't seem to apply to joined tables. Admittedly, an alias is not necessary in a joined table, but the error seems to make a wrong statement. or are joined tables not considered derived tables? -- from P.M.

Drew response:

in what you wrote from the beginning up through the words "which was not there before", well from my angle of reading that in just its own context not related to any other piece of code or where that code has been modified in some other state not shown, then Table1 and Table2 do exist or the join would fail. Right?

In the last third of what you wrote, I would say this: A table is either real or derived. If it is derived it needs a name, as seen in http://pastie.org/10379926 in lines 32 and 34 for an Answer I wrote up for this question: http://tinyurl.com/nhsmmyx

In line 34 I had to plop a y. Or I could have said "as y" but I am lazy. I would argue that I should not have to even do the "y" at all, as my outer-moust select of all that is inside is just the finishing touches and just should lazily give me the columns of the whole inner and be done with it. But mysql gives me "Error Code 1248: Every derived table must have its own alias" if I don't.

The reason on line 27 that I did "t" (or I could have said "as t") is because I am lazy and will bank on it in line 33, too lazy there to do "... and thing1.theDate<=x.xDate".

I hope this helps.

Drew
  • 24,851
  • 10
  • 43
  • 78
  • Wow you even answered on my deleted comment, thank you very much! It has gotten more understandable for me now, though I still don't feel 100% clear about it. But at least I practically know now that I have to give an additional name for a derived table when joining it. also your example about the 2 tables with equal field names was very helpful. Unfortunately I'm not such an SQL talent as you obviously are! – Peter Möhrenbart Aug 26 '15 at 01:21
  • hm I guess it is becoming clear now. It's just because of this case where the joined tables would have columns of equal name, is that right? – Peter Möhrenbart Aug 26 '15 at 01:27
  • let me answer a few things. I gave the same names for my columns at the top of my answer to show the problems with `select *` and getting more than you need back, and the possibility of column confusion for the recipient of the resultset. That is all that was about, just because you were doing select * – Drew Aug 26 '15 at 01:33
  • sorry, had to do something, ok, the problem is that part at the very end of my answer. Forget about common column names being the error. If it was an error, mysql will bark about ambiguous columns (as if it doesn't know which table you are referring to). So, the problem is that your very last `on clause` makes reference to the mystery table `TagsSignifikanzQuery` – Drew Aug 26 '15 at 01:51
  • ah yes, I see. I just used `TagsSignifikanzQuery` again instead of `Alias1`in BK's version, that is, the same name as the table it is derived from, so the `on clause` didn't produce an error for me. Anyway that Unknown column error is clear to me. I think I finally got it now. Thank you! Great help!!! – Peter Möhrenbart Aug 26 '15 at 02:32
  • cool. could you give BK the green check mark so he answered it. You get points too that way. thx and good luck ! – Drew Aug 26 '15 at 02:59
  • I did that, after correcting the `on clause` thing. I noticed that not only `TagsSignifikanzQuery` needed to be replaced with `Alias1`, but also the other table name in the `on clause` had to be changed (originally `TagsUndTitelSignifikanzTable` now renamed `Alias2`. I called that TagsUndTitelSignifikanzTable cause I thought it was referring to the new joined table as a whole, but in fact it names only the 2nd table for the join. (why does the joined table not need an `AS clause`? It is a derived table as well, I would say) – Peter Möhrenbart Aug 26 '15 at 16:02
  • @BK435 hmm I edited YOUR post accordingly, but now it seems to be back to how it was before and it says edited 18 hours ago though I edited it 1 hour ago o.O apparently it didn't get edited... I will add the final version to my original post – Peter Möhrenbart Aug 26 '15 at 17:56
  • @BK435 well it has nothing to do with what my query looks like now. I just mean, in the query – Peter Möhrenbart Aug 27 '15 at 15:18
  • ... in the query "SELECT * FROM Table1 JOIN Table2" there is no AS clause needed although I would say you select data from a joined table which was not there before, i. e. a derived table. But the MySQL error goes "a derived table always needs an alias" or so, but it doesn't seem to apply to joined tables. Admittedly, an alias is not necessary in a joined table, but the error seems to make a wrong statement. or are joined tables not considered derived tables? – Peter Möhrenbart Aug 27 '15 at 15:27