I have two tables. To simplify:

Table 1 has two columns, AppID and AppPlayerID

Table 2 has two columns, SubID and SubPlayerID

I have another table which has a list of players, which, among others, will have a field called PlayerID.

In relation to Table 1 and Table 2, AppPlayerID and SubPlayerID both refer to PlayerID.

What I want to do is use COUNT in a query, to count the amount of times each PlayerID appears in both Table 1 and Table 2.

I can do this one for one table, but I have no idea how to combine the two tables and count the AppPlayerID and SubPlayerID instances together.

Can anyone offer any assistance on how to do this, or perhaps post a simple example?

    I've read about it, but have yet to come across a simple example that I can use to incorporate it.

    At the moment, I am only counting the Apps table using the following:

    $get_apps = mysql_query("
    SELECT P.PlayerID AS id,
    COUNT(A.AppearancePlayerID) AS apps
    FROM tplss_players P, tplss_appearances A
    WHERE P.PlayerID = A.AppearancePlayerID
    GROUP BY id
    ORDER BY 'apps' DESC
    LIMIT 0, 1
    ",$connection)
    or die(mysql_error());

    This works fine for Apps on it's own, or indeed for Subs on it's own, but I want something that will COUNT both at the same time. Will JOIN do this? If so, may I ask how?

      Well, it sounds like you want something like:

      SELECT Table1.AppPlayerID, COUNT(Table1.AppPlayerID)
          FROM Table1 JOIN Table2 ON Table1.AppPlayerID=Table2.SubPlayerID
          GROUP BY Table1.AppPlayerID;

        I've had a try with the above.

        Not sure what I'm doing wrong but the query is just timing out.

        $get_apps = mysql_query("
        SELECT tplss_players.PlayerID AS id,
        tplss_players.PlayerLastName AS lastname,
        tplss_players.PlayerFirstName AS firstname,
        tplss_appearances.AppearancePlayerID,
        COUNT(tplss_appearances.AppearancePlayerID) AS apps
        FROM tplss_appearances, tplss_players
        JOIN tplss_substitutions 
        ON tplss_appearances.AppearancePlayerID = tplss_substitutions.SubstitutionPlayerIDIn
        GROUP BY tplss_appearances.AppearancePlayerID
        ORDER BY 'apps' DESC
        LIMIT 0, 10
        ",$connection)
        or die(mysql_error());
        
        while($data = mysql_fetch_array($get_apps))
        	{
        
        echo"
        <tr>
        <td width=\"160\"></td>
        <td>
        
        <a href=\"player.php?id=$data[id]\">$data[firstname] $data[lastname]</a> - $data[apps]
        
        </td>
        </tr>";
        
        }
        

          Note that this is alternative syntax for a JOIN (an INNER JOIN) of tplss_appearances on tplss_players:

          FROM tplss_appearances, tplss_players

          So if the query is taking a long time, it is because you have a Cartesian product unconstrained by a join condition.

            Always test your SQL queries in your database first. You don't need to debug two languages at once.

              laserlight;11009315 wrote:

              Note that this is alternative syntax for a JOIN (an INNER JOIN) of tplss_appearances on tplss_players:

              FROM tplss_appearances, tplss_players

              So if the query is taking a long time, it is because you have a Cartesian product unconstrained by a join condition.

              Afraid you've completely lost me. I'm a bit of a novice and quite new to SQL. What do you recommend I do to amend this?

                NiallThistle wrote:

                Afraid you've completely lost me. I'm a bit of a novice and quite new to SQL. What do you recommend I do to amend this?

                You need to have a join condition when joining tplss_appearances and tplss_players. The problem is, now that you real query is different from what you gave in your example query, the exact join to choose and such may be different, depending on what exactly you want.

                Basically, I think the problem here is that your knowledge of joins is deficient. What material did you use to read up on them?

                  NiallThistle;11009323 wrote:

                  Afraid you've completely lost me. I'm a bit of a novice and quite new to SQL. What do you recommend I do to amend this?

                  The number of join conditions is (n-1), if there are more than two tables joined in a query where 'n' is the number of tables involved. The rule must be true to avoid Cartesian product.

                  More here.

                    The number of join conditions is (n-1), if there are more than two tables joined in a query where 'n' is the number of tables involved. The rule must be true to avoid Cartesian product.

                    Heh, "if there are more than two tables joined in a query" sounds like an unnecessarily strict condition. If there are two tables joined in a query, then the number of join conditions to avoid a Cartesian product would be 2-1=1. If there is only one table joined in a query, i.e., there is no join, then the number of join conditions to avoid a Cartesian product would be 1-1=0. So, the condition need only be "if there is at least one table involved in a query".

                      I don't have any major knowledge of joins other than examples I've read on Google, but none that pertain specifically to what I'm looking for.

                      My updated example returns a result, but the problem now that is that it returning each player with a count for all players, as opposed to just that one.

                      $get_apps = mysql_query("
                       SELECT P.PlayerID AS id,
                        P.PlayerLastName AS lastname,
                        P.PlayerFirstName AS firstname,
                        COUNT(A.AppearancePlayerID) AS apps
                        FROM tplss_appearances A, tplss_players P
                        LEFT JOIN tplss_substitutions S
                        ON A.AppearancePlayerID = S.SubstitutionPlayerIDIn
                        WHERE P.PlayerID = A.AppearancePlayerID
                        GROUP BY id
                        ORDER BY apps DESC
                        LIMIT 0, 10
                      ",$connection)
                      or die(mysql_error());
                      
                      while($data = mysql_fetch_array($get_apps))
                      	{
                      
                      echo"
                      <tr>
                      <td width=\"160\"></td>
                      <td>
                      
                      <a href=\"player.php?id=$data[id]\">$data[firstname] $data[lastname]</a> - $data[apps]
                      
                      </td>
                      </tr>";
                      
                      }

                        I think the thing that is confusing me most here, is how do I specify in the query that both A.AppearancePlayerID and S.SubstitutionPlayerID have to match P.PlayerID in terms of which player the appearances and substitutions are referring to. I am used to being able to just specify that in the WHERE line, but when it comes to using a join and having two different tables, I am lacking the knowledge to be able to write this query.

                          NiallThistle wrote:

                          I don't have any major knowledge of joins other than examples I've read on Google, but none that pertain specifically to what I'm looking for.

                          Searching for specific solutions is one approach, but getting a general overview and actually learning about a topic can pay off better in the long run.

                          NiallThistle wrote:

                          My updated example returns a result, but the problem now that is that it returning each player with a count for all players, as opposed to just that one.

                          Sounds like a matter of figuring out what exactly to COUNT and what exactly to GROUP BY. I'm afraid that I don't deal with SQL directly often enough to tell you what to do without testing it myself, and I don't feel like setting up something to test with when it is past midnight here.

                          Here's what I suggest: simplify your example and/or query and test. As Bunkermaster recommended, test with your database first, e.g., using something like phpmyadmin, or in the database shell. See how the result sets respond when you change the SQL: this will give you an understanding of what you are doing. In other words, take this opportunity to learn SQL.

                          NiallThistle wrote:

                          how do I specify in the query that both A.AppearancePlayerID and S.SubstitutionPlayerID have to match P.PlayerID in terms of which player the appearances and substitutions are referring to.

                          You specified that with "A.AppearancePlayerID = S.SubstitutionPlayerIDIn" and "P.PlayerID = A.AppearancePlayerID".

                            Following the guides I've found, this appears to be the simplest way I can do it, yet it still returns ridiculously incorrect counts for each.

                            $get_apps = mysql_query("
                            SELECT tplss_appearances.AppearancePlayerID as id,
                            COUNT(tplss_appearances.AppearancePlayerID) as apps
                            FROM tplss_appearances
                            JOIN tplss_substitutions
                            ON tplss_appearances.AppearancePlayerID = tplss_substitutions.SubstitutionPlayerIDIn
                            GROUP BY tplss_appearances.AppearancePlayerID
                            ORDER BY apps DESC
                            LIMIT 0, 10
                            ",$connection)
                            or die(mysql_error());

                            Anything obvious I've missed?

                              Latest now, using LEFT JOIN.

                              $get_apps = mysql_query("
                               SELECT tplss_appearances.AppearancePlayerID as id,
                                COUNT(tplss_appearances.AppearancePlayerID) as apps
                                FROM tplss_appearances
                                LEFT JOIN tplss_substitutions
                                ON tplss_appearances.AppearancePlayerID = tplss_substitutions.SubstitutionPlayerIDIn
                                GROUP BY tplss_appearances.AppearancePlayerID
                                ORDER BY apps DESC
                                LIMIT 0, 5
                              ",$connection)
                              or die(mysql_error());

                              Figured out by looking at the results that it appears to be counting Apps correctly, but not Subs. When it adds the Subs count onto the Apps count, it seems to add thousands onto the total. In the case where a player has 0 entries in Subs, the Apps figure is accurate.

                              Why would the Subs be counting 1000+ times more than it should?

                                NiallThistle;11009341 wrote:

                                Following the guides I've found, this appears to be the simplest way I can do it, yet it still returns ridiculously incorrect counts for each.

                                $get_apps = mysql_query("
                                SELECT tplss_appearances.AppearancePlayerID as id,
                                COUNT(tplss_appearances.AppearancePlayerID) as apps
                                FROM tplss_appearances
                                JOIN tplss_substitutions
                                ON tplss_appearances.AppearancePlayerID = tplss_substitutions.SubstitutionPlayerIDIn
                                GROUP BY tplss_appearances.AppearancePlayerID
                                ORDER BY apps DESC
                                LIMIT 0, 10
                                ",$connection)
                                or die(mysql_error());

                                Anything obvious I've missed?

                                Would you mind posting an example database? Twenty or so lines in plain text, perhaps?

                                Laserlight's point is well-taken; it can't hurt to learn about some things like DISTINCT, SUM, and how to do subqueries for things like this ... maybe. I can't quite picture your data to say for sure.

                                  NiallThistle;11009347 wrote:

                                  Latest now, using LEFT JOIN.

                                  Why would the Subs be counting 1000+ times more than it should?[/QUOTE]Ostensibly, because the tables are joined.
                                    dalecosp;11009349 wrote:

                                    Would you mind posting an example database? Twenty or so lines in plain text, perhaps?

                                    Laserlight's point is well-taken; it can't hurt to learn about some things like DISTINCT, SUM, and how to do subqueries for things like this ... maybe. I can't quite picture your data to say for sure.

                                    tplss_appearances

                                    AppearanceID | AppearancePlayerID

                                    1 | 5
                                    2 | 13
                                    3 | 14
                                    4 | 8
                                    5 | 9
                                    6 | 12

                                    tplss_substitutions

                                    SubstitutionID | SubstitutionPlayerIDIn

                                    1 | 3
                                    2 | 14
                                    3 | 23
                                    4 | 3
                                    5 | 12
                                    6 | 15

                                    Basically, appearances and substitutions are the same thing, but substitutions are only partial appearances. What I'm trying to do with this data is to display a list of 20, 30, or 50, or however many players I want, in a list - and next to their name (or ID number), will be a list of their "total appearances", which essentially is the number of times they have been on the field (both full appearances and substitute appearances).

                                    So, using the data above, Player No 12, will have one sub appearance (entry 5 in tplss_substitutions) and one full appearance (entry 6 in tplss_appearances), so his total should be 2.

                                    I hope this explains it.

                                      You can't join both tables in one (non-sub-)query. Let's say first table contains 3 occurances for one player id and the second contains 3. After the first join, you have 3 rows with that player id, each of which will join against 3 rows in the second table for the same id. Thus, you will get 3*3 rows = 9 rows, which are then grouped.
                                      You can however do it using a subquery. Let the inner query deal with one of the tables, using count and group by. Then let the outer query do the same on the other table, and then also join on the subquery (which must be given an alias).

                                      CREATE TABLE player (
                                      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                                      name VARCHAR(10)
                                      );
                                      
                                      CREATE TABLE full (
                                      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                                      player INT UNSIGNED NOT NULL,
                                      FOREIGN KEY (player) REFERENCES player(id)
                                      );
                                      CREATE TABLE partial (
                                      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                                      player INT UNSIGNED NOT NULL,
                                      FOREIGN KEY (player) REFERENCES player(id)
                                      );
                                      
                                      INSERT INTO player(name) VALUES
                                      ('Alpha'),
                                      ('Bravo'),
                                      ('Charlie'),
                                      ('Delta');
                                      
                                      INSERT INTO full(player) VALUES
                                      (1),
                                      (4),
                                      (1),
                                      (1),
                                      (2),
                                      (2),
                                      (2),
                                      (4);
                                      
                                      INSERT INTO partial(player) VALUES
                                      (3),
                                      (1),
                                      (3),
                                      (2),
                                      (2),
                                      (2);
                                      
                                      
                                      SELECT p.id, p.name, COUNT(part.id) as part, t.full, COUNT(part.id) + t.full AS part_and_full
                                      FROM player p
                                      LEFT JOIN partial part ON p.id = part.player
                                      LEFT JOIN
                                      (
                                        SELECT p.id, COUNT(f.id) as full
                                        FROM player p
                                        LEFT JOIN full f ON p.id = f.player
                                        GROUP BY p.id
                                      ) t ON t.id = p .id
                                      GROUP BY p.id, p.name;