7
<?php

$query1 = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";

$query2 = "CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date = date_sub('X', INTERVAL 1 MONTH)";

$query3 = "CREATE VIEW final_output AS SELECT current_rankings.player, current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
             ON (current_rankings.player = previous_rankings.player)";

$query4 = "SELECT *, @rank_change = prev_rank - current_rank as rank_change from final_output";

$result = mysql_query($query4) or die(mysql_error()); 

while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}

?>

All the queries work independently but am really struggling putting all the pieces together in one single result so I can use it with mysql_fetch_array.

I've tried to create views as well as temporary tables but each time it either says table does not exist or return an empty fetch array loop...logic is there but syntax is messed up I think as it's the 1st time I had to deal with multiple queries I need to merge all together. Looking forward to some support. Many thanks.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Naim
  • 471
  • 1
  • 4
  • 14
  • i'm quite certain there's a much more efficient way of doing this, but without details about those tables, it's a little hard to say. – GDP May 16 '12 at 00:52
  • Actual queries are much longer, I've tried to ask a compact question for a better overall picture. Nonetheless, the structure is there and further details are not relevant as it comes at the end to merge all 4 queries or execute them one after the other. – Naim May 16 '12 at 00:56
  • Why do you need to keep creating the views? Doesn't the view basically save your query and runs it again when you select from it? – Gohn67 May 16 '12 at 01:28
  • exactly and this is why I use them. The results are cascading down from the parent views. – Naim May 16 '12 at 01:31

3 Answers3

23

Thanks to php.net I've come up with a solution : you have to use (mysqli_multi_query($link, $query)) to run multiple concatenated queries.

 /* create sql connection*/
$link = mysqli_connect("server", "user", "password", "database");

$query = "SQL STATEMENTS;"; /*  first query : Notice the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS"; /* last query : Notice the dot before = at the end ! */

/* Execute queries */

if (mysqli_multi_query($link, $query)) {
do {
    /* store first result set */
    if ($result = mysqli_store_result($link)) {
        while ($row = mysqli_fetch_array($result)) 

/* print your results */    
{
echo $row['column1'];
echo $row['column2'];
}
mysqli_free_result($result);
}   
} while (mysqli_next_result($link));
}

EDIT - The solution above works if you really want to do one big query but it's also possible to execute as many queries as you wish and execute them separately.

$query1 = "Create temporary table A select c1 from t1"; 
$result1 = mysqli_query($link, $query1) or die(mysqli_error());

$query2 = "select c1 from A"; 
$result2 = mysqli_query($link, $query2) or die(mysqli_error());

while($row = mysqli_fetch_array($result2)) {

echo $row['c1'];
    }  
Naim
  • 471
  • 1
  • 4
  • 14
  • 1
    **Don't use `mysqli_multi_query()`**. You should execute all these queries separately. – Dharman Apr 04 '20 at 19:23
  • 1
    [Explanation](https://stackoverflow.com/a/58783101/2408212) of why `mysqli_multi_query()` should be avoided. – Xonshiz Jul 19 '20 at 11:55
0

It seems you are not executing $query1 - $query3. You have just skipped to $query4 which won't work if the others have not been executed first.

Also

$query4 = "SELECT *, @rank_change = prev_rank - current_rank as rank_change from final_output";

should probably be

$query4 = "SELECT *, @rank_change := prev_rank - current_rank as rank_change from final_output";

or else the value of rank_change will just be a boolean, true if @rank_change is equal to (prev_rank - current_rank), false if it is not. But do you need @rank_change at all? Will you use it in a subsequent query? Maybe you can remove it altogether.

Even better, you could just combine all the queries into one like this:

SELECT 
    curr.player,
    curr.rank AS current_rank,
    @rank_change := prev.rank - curr.rank AS rank_change
FROM
    main_table AS curr
    LEFT JOIN main_table AS prev
        ON curr.player = prev.player    
WHERE 
    curr.date = X
    AND prev.date = date_sub('X', INTERVAL 1 MONTH)
Okonomiyaki3000
  • 3,628
  • 23
  • 23
  • True, but this is exactly what I am trying to figure out : how to execute all 4 queries. – Naim May 16 '12 at 00:52
  • You can just run them one after another with multiple calls to mysql_query() or concatenate them as suggested by Paul, or rewrite them as one query (in my edit above). – Okonomiyaki3000 May 16 '12 at 01:03
  • Thanks Elijah, but running one single query is impossible in my case, as I need very complex queries from main_table, so I have to go step by step using sub-queries. Will try Paul's suggestion and revert back to him. – Naim May 16 '12 at 01:12
  • I don't know about other queries you may be running on this table but, in this instance, you can certainly do it with one relatively simple query. – Okonomiyaki3000 May 18 '12 at 00:22
  • @ Elijah - That would be ideal, still am not sure it would be possible as every query contains multiple sub-queries and use different user variables...will post as a new question and post the link here for you. Thanks. – Naim May 18 '12 at 22:49
  • Yeah, let me have a look at some of those. Maybe some of them can be simplified. – Okonomiyaki3000 May 21 '12 at 00:32
-1

You should concatenate them:

<?php

$query = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";

$query .= " CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date =     date_sub('X', INTERVAL 1 MONTH)";

$query .= " CREATE VIEW final_output AS SELECT current_rankings.player,     current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
         ON (current_rankings.player = previous_rankings.player)";

$query .= " SELECT *, @rank_change = prev_rank - current_rank as rank_change from final_output";

$result = mysql_query($query) or die(mysql_error()); 

while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}

?>
Paul Dessert
  • 6,363
  • 8
  • 47
  • 74
  • 2
    Don't forget your semicolons. – Okonomiyaki3000 May 16 '12 at 01:01
  • @ElijahMadden - Where did I forget a `;` ? – Paul Dessert May 16 '12 at 01:04
  • 1
    Your queries will need them if you concatenate into a single string. – Okonomiyaki3000 May 16 '12 at 01:10
  • Hi Paul I've added this dot before = as showed in your answer and it returned a SQL syntax error... – Naim May 16 '12 at 01:23
  • @ElijahMadden could you please tell me where I should put those semi colons ? – Naim May 16 '12 at 17:58
  • @Paul - Thanks Paul but I haven't noticed anything different after the edit, it looks like the exact same code as yesterday to me..am I missing something??? – Naim May 16 '12 at 22:20
  • @Naim - I added spaces after some of the `"` i.e. `" CREATE VIEW ` Now has a space in front of it. – Paul Dessert May 16 '12 at 22:23
  • @Paul, it worked even though I got another error saying I can't use `create view` on sub-queries or local variables, but that's out of the scope on this question. – Naim May 17 '12 at 10:19
  • 5
    I don't believe that separating these queries by spaces is correct. As each is meant to be a separate query, they should be separated by semicolons. Ex: `$query = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X;";` (notice the semicolon after X, in the query. – Okonomiyaki3000 May 18 '12 at 00:25
  • @ElijahMadden - Thanks and I have just read about it on php.net. Also I am trying now to use `mysqli_multi_query` to run multiple queries but now am getting other type of errors..still digging... – Naim May 18 '12 at 22:47