Multiple query on PHP dows not work - php

Consider this simple PHP page:
<?php
$db = new mysqli("localhost", "myuser", "mypwd", "mydb");
if ($db->connect_error)
// Dying sequence;
// Executing query
$qres = $db->multi_query("SET #rank = -1; SELECT * FROM (SELECT #rank := #rank + 1 as rank, field1, field2 FROM mytable WHERE field1 = 'value') AS T1 WHERE rank = 2;");
$db->commit();
if (!qres) {
// Problems in query
// Dying
$db->close();
return;
}
if (!($qres->num_rows == 1)) {
// Error fetched
$numrows = $qres->num_rows;
$db->close();
// Dying
return;
}
// Returning
echo "ALLOK";
$db->close();
?>
Well, this does not work.
either if I use query or multi_query
Can you help me?

It looks like you just want to select the 3rd row from some table. Though the rank will be nondeterministic since you don't specify an ORDER BY clause for that inner query.
You don't need this variable and multiple queries to do that.
Use an offset in the LIMIT clause, along with an ORDER BY clause, instead.
SELECT field1, field2 FROM mytable WHERE field1 = 'value' ORDER BY something LIMIT 2,1

Related

Using Limit in SQL according to row_count

I want to fetch number of rows with highest number of multiple of 20, Like if my table have 148 rows then limit should be 140 leaving the latest 8 entry behind, or if my table have 170 rows then limit will be 160. What will be the query in this case.
$conn = mysqli_connect($server_name, $mysql_username, $mysql_password,
$db_name);
if($conn === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
$number= $_POST['number'];
$sql1 = "SELECT * FROM abc_table LIMIT WHAT TO ENTER HERE ";
As far as I know, what follows LIMIT has to be an integer literal. LIMIT won't even take something like 6/2, which would evaluate to an integer literal. I recommend just reading in the entire table, and then only processing how many rows you need in PHP.
$row_cnt = $result->num_rows;
$rs_size = $row_cnt - ($row_cnt % 20);
while ($rs_size > 0 && $row = mysqli_fetch_assoc($result)) {
// process a row
--$rs_size;
}
The above while loop should exit after reading the greatest number of multiples of 20 available. This approach is not too wasteful, since at most you would be reading in 19 extra rows from MySQL which you would end up not using.
You can use variables for this:
select t.*
from (select t.*, (#rn := #rn + 1) as rn
from t cross join
(select #rn := 0) params
order by ?
) t
where rn <= floor(rn / 20) * 20;
The ? is for the column used to specify the ordering, presumably something like id asc.
In MySQL 8+, you would use window functions:
select t.*
from (select t.*,
row_number() over (order by ?) as seqnum,
count(*) over () as cnt
from t
) t
where seqnum <= floor(cnt / 20) * 20;

Commands out of sync in A correct code

I've the following query executed via PHP, it used to work like yesterday, and stopped working today, here's it :
SELECT
*,
(SELECT IF (pro.uid= '4342','True','False') FROM pro) AS 'uid'
FROM
Episodes, pro
ORDER BY
Episodes.id DESC
LIMIT 9
The '4342' is changed with GET param, I'm having the following error :
Commands out of sync; you can't run this command now
My PHP API is as the following ( snippets ) :
<?php
include_once "db_config.php";
DEFINE ('DB_HOST', $host);
DEFINE ('DB_USER', $user);
DEFINE ('DB_PASSWORD', $pass);
DEFINE ('DB_NAME', $database);
$mysqli = #($GLOBALS["___mysqli_ston"] = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD)) OR die ('Could not connect to MySQL');
#((bool)mysqli_query($GLOBALS["___mysqli_ston"], "USE " . constant('DB_NAME'))) OR die ('Could not select the database');
?>
<?php
if(isset($_GET['meaE'], $_GET['uid']))
{
$query="SELECT * , (SELECT IF (pro.uid= '".$_GET['uid']."','True','False') FROM pro ) AS 'uid' FROM Episodes,pro ORDER BY Episodes.id DESC LIMIT 9
";
$resouter = mysqli_query($GLOBALS["___mysqli_ston"], $query);
}
$set = array();
$total_records = mysqli_num_rows($resouter);
if($total_records >= 1){
while ($link = mysqli_fetch_array($resouter, MYSQLI_ASSOC)){
$set['APITest'][] = $link;
}
}
echo $val= str_replace('\\/', '/', json_encode($set));
?>
I want to have the following output :
TABLE A - TABLE B
ID NAME TEXT UID - Check_ID
The query I want :
Select * From Table A, Check if "134123123" is exists in B, if yes / no add a record for all the taken records from Table A with the value of checking (True/False) .
What's happening with #sagi query is :
There are 3 records in Table B, and 10 records in Table A, when the query is executed, the result is 30 records, each record in Table B has 10 records from Table A, and the "uid" record value is True where the uid is '134123123', and it's false where it's not '134123123' .
Your query seems wrong, I don't know how it worked yesterday, but right now your are cross joining with out a condition (could be correct but I doubt it) - that means each record in episodes will be joined to each record in pro . In addition, your subquery with the IF will return more then 1 record unless this table contains only 1 record (which again - I doubt it) .
Try this:
SELECT distinct t.*, IF (s.uid is null,'True','False') AS 'uid'
FROM Episodes t
Left JOIN pro s
ON(s.uid = '4342')
ORDER BY t.id DESC
LIMIT ?????
Try using a sub query instead of a join:
Select t.*,
Case when exists(select 1 from pro s where s.uid = '4342')
Then 'true' else 'false'
End as 'uid'
From episodes t
Order by t.id desc
Limit 9;

How Can I Skip every other row in mysql?

i have a table in mysql and i am fetching the results from this table. but instead of fetching all the rows in this table i only want to fetch every other row. so first get row one then skip the second row, get row 3 and skip row 4 etc.
Is there a way of doing this and if so can someone please show me how.
I've tried this:
function:
function blocked_users_list() {
global $connection;
global $_SESSION;
global $profile_id;
$query = "SELECT
baseview.*
#odd:=1-#odd AS even
FROM
(
SELECT *
FROM ptb_block_user
WHERE
WHERE ptb_block_user.blocked = '1'
AND ptb_block_user.blocked_id = ".$_SESSION['user_id']."
) AS baseview,
(
SELECT #odd:=0
) AS filter
WHERE
even=1
";
$blocked_users_list = mysql_query($query, $connection);
confirm_query($query, $connection);
return $blocked_users_list;
}
php:
<?php
$blocked_users_list = blocked_users_list();
while ($block = mysql_fetch_array($blocked_users_list)) {
?>
but it gives this error:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /Applications/XAMPP/xamppfiles/htdocs/ptb1/blocked_users.php on line 44
do it in the query:
SELECT *
FROM (
SELECT
#row := #row +1 AS rownum, [column name]
FROM (
SELECT #row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
You can use modulus in mysql (one query)
select * from `table` where `id` % 2 = 1
Retrieves all odd IDs.
Assuming you have a query like
SELECT
col1 AS colA,
col2 AS colB
FROM
sometable
WHERE
something=17
that fetches all rows as a baseline. You can then filter every second row by using
SELECT
baseview.*
#odd:=1-#odd AS even
FROM
(
SELECT
col1 AS colA,
col2 AS colB
FROM
sometable
WHERE
something=17
) AS baseview,
(
SELECT #odd:=0
) AS filter
WHERE
even=1
Use a variable to record the index, then check with mod 2 ($ind % 2) - this will return either 0 or 1.
<?php
$users_list = users_list();
$ind = 0;
while ($user = mysql_fetch_array($users_list)) {
if(($ind++)%2) echo "something";
}
?>

SQL query construction

I recently created a scoring system where the users are ordered by their points on descending basis. First I used to store ranks in a column of its own. I used to run this loop to update the rank:
$i = 1;
$numberOfRows = mysql_query('SELECT COUNT(`id`) FROM sector0_players');
$scoreboardquery = mysql_query("SELECT * FROM sector0_players ORDER BY points DESC");
while(($row = mysql_fetch_assoc($scoreboardquery)) || $i<=$numberOfRows){
$scoreid = $row['id'];
$mysql_qeury = mysql_query("UPDATE sector0_players SET scoreboard_rank = '$i' WHERE id = '$scoreid'");
$i++;
}
And it was really hard, not to mention slow to actually run this on a huge amount of users.
Instead, I tried to construct a query and ended up with this.
SET #rownum := 0;
SELECT scoreboard_rank, id, points
FROM (
SELECT #rownum := #rownum + 1 AS scoreboard_rank, id, points FROM sector0_players ORDER BY points DESC
)
as result WHERE id = '1';
But, this is just a select statement. Is there anyway I could get around it and change it so that it updates the table just as the loop does?
Please try using the following query :
set #rownum:=0;
update sector0_players set scoreboard_rank=#rownum:=#rownum+1 ORDER BY points DESC;
PHP code can be ,
mysql_query("set #rownum:=0;");
mysql_query("update sector0_players set scoreboard_rank=#rownum:=#rownum+1 ORDER BY points DESC;");
You can try using the RANK function .. I haven't actually executed the SQL, but it should work
UPDATE sector0_players
SET scoreboard_rank =
(
SELECT srank
FROM
(
SELECT id,points, RANK() OVER (ORDER BY points) AS srank
FROM sector0_players T
) D
WHERE D.id = sector0_players.id
AND D.points = sector0_players.points
)

MySQL query returns rows in mysql but empty set in PHP

The following MySQL query runs in PHP without errors, but the resultset is empty. Directly outputting the query string to a file and running the query in the MySQL client using 'source [filename]' returns several rows of results, as expected.
Is there something that would cause this query not to work with PHP? categorylinks.cl_to and smw_spec2.value_string are both varbinary(255). Show create table indicates engine=InnoDB and default charset=binary.
Things I have tried without success:
$sql = preg_replace("/[\n\t]+/", " ", $sql);
Changing '_wpg' and 'Derp' to CAST('_wpg' AS BINARY(255))
Changing '_wpg' and 'Derp' to BINARY '_wpg'
I am using the MediaWiki DatabaseMysql class to execute the query and fetch rows, but it's a very thin abstraction, and I'm certain it's not the problem (see below).
SELECT
prop.name AS prop_name, prop.count AS prop_count, prop.type AS prop_type,
val.value AS val_value, val.unit AS val_unit, val.count AS val_count
FROM
(
SELECT
s_id, name, type, COUNT(foo.name) AS count
FROM (
(
SELECT
cl.cl_to AS cat_name, s.smw_id AS s_id, s.smw_sortkey AS name, spec.value_string AS type
FROM `smw_ids` s
INNER JOIN (`categorylinks` cl, `page` p, `smw_ids` s2, `smw_atts2` a)
ON (cl.cl_from = p.page_id AND
p.page_title = s2.smw_title AND
s2.smw_id = a.s_id AND
a.p_id = s.smw_id)
LEFT JOIN `smw_spec2` spec ON s.smw_id = spec.s_id
)
UNION ALL
(
SELECT
cl.cl_to AS cat_name, s.smw_id AS s_id, s.smw_sortkey AS name, '_wpg' AS type
FROM `smw_ids` s
INNER JOIN (`categorylinks` cl, `page` p, `smw_ids` s2, `smw_rels2` a)
ON (cl.cl_from = p.page_id AND
p.page_title = s2.smw_title AND
s2.smw_id = a.s_id AND
a.p_id = s.smw_id)
)
) AS foo
WHERE foo.cat_name = 'Derp'
GROUP BY name
ORDER BY count DESC
LIMIT 10
) AS prop
INNER JOIN
(
SELECT
bar.p_id AS p_id, bar.value AS value, bar.unit AS unit, COUNT(bar.value) AS count,
IF( #prev != p_id, #rownum := 1, #rownum := #rownum+1 ) AS rank,
#prev := p_id
FROM (
(SELECT a.p_id AS p_id, a.value_xsd AS value, a.value_unit AS unit FROM `smw_atts2` a)
UNION ALL
(SELECT r.p_id AS p_id, s.smw_sortkey AS value, NULL AS unit
FROM `smw_rels2` r INNER JOIN `smw_ids` s ON r.o_id = s.smw_id)
) AS bar
GROUP BY value, unit
ORDER BY count DESC
) AS val
ON prop.s_id = val.p_id
WHERE val.rank <= 50
ORDER BY prop_count DESC, prop_name, val_count DESC, val_value
Edit: The following test script outputs nothing. query.sql contains exactly the query above, written to file immediately preceding the mysql_query() call in MediaWiki's database class.
$db = mysql_connect('localhost', 'root', '');
mysql_select_db('mediawiki', $db);
$res = mysql_query(file_get_contents("query.sql"), $db);
while ($row = mysql_fetch_assoc($res)) {
var_dump($row);
}
echo mysql_error($db);
Edit: I imported a huge database dump and afterwards, when I loaded the PHP page, there was a noticeable wait that seemed to indicate that the query was running, but still no results showed. I ended up reworking the query, and I no longer have this problem.
Try this to detect and report errors better:
$db = mysql_connect('localhost', 'root', '');
mysql_select_db('mediawiki', $db);
$res = mysql_query(file_get_contents("query.sql"), $db);
if (!$res) {
print "SQL Error ".mysql_errno().":".mysql_error().", from query: '".file_get_contents("query.sql")."'";
} else {
while ($row = mysql_fetch_assoc($res)) {
var_dump($row);
}
}
Try this after mysql_connect:
mysql_query('SET NAMES utf8;');

Categories