Would like to know how come my SQL update case is not functioning correctly.
I already have values:
$usrcustomerid = 110;
$search = 'face';
Looking for a fix on my CASE in SET because there is no update when this SQL triggers
SQL Update code
public function UpdateUserSearch($db, $usrcustomerid, $search) {
$stmt = $db->prepare(
" UPDATE usr_customer
SET search_counter = (CASE WHEN search_counter = 1 THEN 2
WHEN search_counter = 2 THEN 3
WHEN search_counter = 3 THEN 1 END),
search1 = (CASE WHEN search_counter = 1 THEN $search END),
search2 = (CASE WHEN search_counter = 2 THEN $search END),
search3 = (CASE WHEN search_counter = 3 THEN $search END)
WHERE usrcustomerid = $usrcustomerid "
);
$stmt->bindValue(':usrcustomerid', $usrcustomerid, PDO::PARAM_INT);
$stmt->bindValue(':search', $search, PDO::PARAM_STR);
$stmt->execute();
$rowAffected = $stmt->rowCount();
return $rowAffected;
}
table usr_customer
In the picture below, the user's search_counter is set to one and the three search columns have no value inside, so the code, based on my logic in my CASE, should have my "$search" value insert in "search1" and update search_counter from 1 to 2.
PS I am aware of SQL Injection, please do not answer with a reminder because I am trying to get my code working first.
This is not a SQL issue, it is a PHP issue. The values you are replacing in your SQL Query should be prefixed with : instead of $.
" UPDATE usr_customer
SET search_counter = (CASE WHEN search_counter = 1 THEN 2
WHEN search_counter = 2 THEN 3
WHEN search_counter = 3 THEN 1 END),
search1 = (CASE WHEN search_counter = 1 THEN :search END),
search2 = (CASE WHEN search_counter = 2 THEN :search END),
search3 = (CASE WHEN search_counter = 3 THEN :search END)
WHERE usrcustomerid = :usrcustomerid "
See: PHP Documentation
Related
I originally had an SQL statement, this:
SELECT *, COUNT(friend_one) AS pending_count , COUNT(friend_two) AS requests_sent
FROM friends
WHERE friend_one OR friend_two = ?
AND status = ?
In which I assigned my parameters like :
$pending_friend_count_stmt->execute(array($user_id, $status_one));
However, the query was not getting the results I wanted. Someone showed me a different way of doing it, but it has the variable $user_id in it multiple times, so I do not know how to adjust the code to be able to use a parameter.
You can see the new query here:
http://rextester.com/KSM73595
Am I able to just do
SELECT COUNT(CASE WHEN `friend_one` = ? THEN 1 END) as `requests_count`,
COUNT(CASE WHEN `friend_two` = ? THEN 1 END) as `pending_count`
FROM `friends`
WHERE ? IN ( `friend_one` , `friend_two` )
AND `status` = ?
$pending_friend_count_stmt->execute(array($user_id, $user_id, $user_id $status_one));
Using PDO you have the ability to use named parameters, however in your question you want to use 1 parameters for multiple values and that means emulation has to be on:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
Now you can do the following:
$stmt = $db->prepare("SELECT * FROM table WHERE userid = :userid AND userid = :userid");
$stmt->excecute([
':userid' => 1
]);
Resulting in:
"SELECT * FROM table WHERE userid = 1 AND userid = 1"
I have got a table
unam fnam
john alex
alex john
I want a query that returns true if unam 'john' == fnam 'alex' or unam 'alex' == fname 'john'
I dont know how to do it in a single query .
My code
$re = mysql_query("SELECT 1 FROM tab WHERE unam='john' and fnam='alex' LIMIT 1");
$ir = mysql_query("SELECT 1 FROM tab WHERE unam='alex' and fnam='john' LIMIT 1");
if ((!(mysql_num_rows($re))) && (!(mysql_num_rows($ir)))) echo 'not exists';
I have executed 2 seperate queries (one for unam 'john' == fnam 'alex' and other for unam 'alex' == fname 'john', if both the queries do not have any rows it echos not exists.
I was thinking may be it can be optimized to a single query.
You can do an OR conditional to check for multiple different conditions.
SELECT 1
FROM tab
WHERE (unam='john' and fnam='alex')
OR (fnam='john' and unam='alex')
LIMIT 1
You can put your logic in the where clause like this:
select 1
from tab
where (uname = 'john' and fname = 'alex') or
(fname = 'alex' and uname = 'john')
limit 1
By the way, if you want to always return a value, say 0 or 1, you can use aggregation:
select coalesce(max(1), 0) as retval
from tab
where (uname = 'john' and fname = 'alex') or
(fname = 'alex' and uname = 'john')
If no rows are selected, then the max() returns NULL which the coalesce() turns into 0.
You can use OR statement to achieve this.
Try this:
mysql_query("SELECT 1
FROM tab
WHERE
(unam='john' and fnam='alex')
OR
(unam='alex' and fnam='john')
limit 1");
$re = mysql_query("SELECT COUNT(*) FROM tab WHERE (unam='john' and fnam='alex') OR (unam='alex' and fnam='john')");
Just a different approach, using EXISTS, and a different syntax:
SELECT
EXISTS (SELECT NULL FROM names
WHERE (unam, fnam) IN (('john', 'alex'),('alex','john')))
Please see fiddle here.
Is it possible to do this?
Lets say I have a table : data
$id_1 = "checking";
$id_2 = "box";
$id_users = 1;
id id_1 id_2 id_users
1 checking box 1
2 checking circle 1
3 box checking 1
4 box checking 1
$sql = $db->prepare("SELECT COUNT(*) FROM data WHERE ((id_1 = ? AND id_2= ?) OR (id_1 = ? AND id_2 = ?)) AND id_users = ?");
$sql -> execute(array($id_1, $id_2, $id_2, $id_1, $id_users));
echo count($sql);
With this, I'm getting an output of 1 only. Technically I should be getting an output of 3, correct? Because there are 3 possibilities with checking and box.
The SQL is supposed to check either table for the two combinations of checking and box.
Can someone tell me what I'm doing wrong here?
Thanks
It looks like you're count()ing the already-counted SQL COUNTed number of rows.
How about just echo $sql?
$sql = $db->prepare("SELECT COUNT(*) FROM data WHERE ((id_1 = ? AND id_2= ?) OR (id_1 = ? AND id_2)) AND id_users = ?");
$sql->execute(array($id_1, $id_2, $id_2, $id_1, $id_users));
echo $sql->fetch();
What MДΓΓ БДLL said is ok, but you could also use named parameters:
$sql = $db->prepare("SELECT COUNT(*) FROM data WHERE ((id_1 = :id1 AND id_2= :id2) OR (id_1 = :id2 AND id_2 = :id1)) AND id_users = :idusers");
$sql -> execute(array(':id1' => $id_1, ':id2' => $id_2, ':idusers' => $id_users));
And you need to fetch result
$result = $sql->fetch();
echo $result[0];
In your query it seems that you are passing id_1 as parameter to id_2 and id_2 parameter as id_1 so as per your query there is only one combination of id_1 = checking and id_2 = box ,
so you are getting output count as 1
instead of this to avoid parameter confusion use
$sql -> execute(array(':id1' => $id_1, ':id2' => $id_2, ':idusers' => $id_users));
I have two tables like so:
table {node}
`nid`, `uid`, `type`
1 1 basketball
2 1 basketball
3 1 football
4 2 football
5 2 basketball
table {strato_ticket}
`tid`, `author_uid`, `purpose`, `active`
1 1 'Ticket to a basketball game' TRUE
2 1 'Ticket to a football game' TRUE
3 2 'Ticket to a football game' FALSE
I'd like to generate a report that counts the number of each kind of node, and then counts the number of active tickets that each user has associated with that kind of node.
My solution uses a combination of SQL and PHP: I have a PHP loop for each kind of node that I'm interested in, which simplifies the SQL query, and translates from 'type' to 'purpose', eg
$node_types = array('basketball', 'football');
foreach($node_types as $node){
switch($type){
case 'basketball':
$purpose = array('Ticket to a basketball node');
break;
case 'football':
$purpose = array('Ticket to a football game');
break;
}
$where = " WHERE ({strato_ticket}.`purpose` = '"
.implode("' OR {strato_ticket}.`purpose` = '",$purpose)."')";
Finally I have the trouble spot, the SQL query. When I was just counting nodes owned by each user, it worked fine:
$query = "
SELECT uid, count( * ) AS nodes_owned
FROM {node} WHERE `type` = '$type'
GROUP BY uid ORDER BY nodes_owned DESC
";
$query = db_query($query);
output:
Now displaying info for basketball.
uid nodes_owned
1 2
2 1
Now displaying info for football.
uid nodes_owned
1 1
2 1
But now that I need to query against another table, strato_ticket, things get complicated, and my query is returning FALSE without throwing an error (I think).
$query = "
SELECT count(*) as tickets
FROM {strato_ticket} INNER JOIN (
SELECT node.uid, count( * ) AS nodes_owned
FROM {node} WHERE `type` = '$type'
GROUP BY uid
) AS {nodecount}
ON {strato_ticket}.`author_uid` = {nodecount}.`uid`
$where
GROUP BY nodecount.uid ORDER BY nodecount.nodes_owned DESC
";
$query = db_query($query);
I'm not very good with SQL and I'm not quite sure how it's broken. Could use a little help?
Ideally would like to see
uid nodes_owned tickets
//basketball
1 2 1
2 1 0
//football
1 1 1
2 1 0
Aside from the placeholders, which I can get to later, I think this solves it.
$form = array();
$node_types = array('basketball','football');
// if($user->uid == 1){
$form[$type][] = array('#value'=>"Showing how many of each node type each user owns.".'<br/>');
foreach($node_types as $type){
// Count the number of nodes each user owns of $type.
$form[$type][] = array('#value'=>"Now displaying info for $type".'s. <br/>');
switch($type){
case 'basketball':
$purpose = array('ticket to a basketball game', 'basketball');
break;
case 'football':
$purpose = array('ticket to a football game');
break;
}
$purpose = implode("', '", $purpose);
//#todo : Make a temporary table to query against so I'm not hitting node table multiple times.
$ticketquery = "
SELECT author_uid, purpose, COUNT( * ) AS invitees_accepted
FROM {strato_ticket}
WHERE purpose IN ('$purpose')
GROUP BY author_uid, `purpose`
";
$nodequery = "
SELECT node.uid, count( * ) AS nodes_owned, type
FROM {node}
WHERE `type` IN ('$type')
GROUP BY uid, type";
$query = "
SELECT * FROM
($nodequery) AS nt
JOIN
($ticketquery) AS tt
ON nt.uid = tt.author_uid
GROUP BY nt.uid ORDER BY nt.nodes_owned DESC
";
drupal_set_message('Query is <br/>'.$query);
//return;
$query = db_query($query);
$first = true;
while ($rec = db_fetch_object($query)){
if($first){
$form[$type][] = array('#value'=>"And the winner is: ".print_r($rec, true).'<br/>');
$first = false;
}
else {
$form[$type][] = array('#value'=>print_r($rec, true).'<br/>');
}
}
// }
}
guys i need to count new private messages and old one from a table
so first thing come to mind is using mysql_num_rows and easy thing to do
// check new pms
$user_id = $userinfo['user_id'];
$sql = "SELECT author_id FROM bb3privmsgs_to WHERE user_id='$user_id' AND (pm_new='1' OR pm_unread='1')";
$result = $db->sql_query($sql) ;
$new_pms = $db->sql_numrows($result);
$db->sql_freeresult($result);
// check old pms
$sql = "SELECT author_id FROM bb3privmsgs_to WHERE user_id='$user_id' AND (pm_new='0' OR pm_unread='0')";
$result = $db->sql_query($sql) ;
$old_pms = $db->sql_numrows($result);
$db->sql_freeresult($result);
but how can i count these two fields just in one statement and shorter lines ?~
Use this query instead:
SELECT SUM(CASE WHEN pm_new = '1' OR pm_unread = '1' THEN 1 ELSE 0 END) AS new_pms,
SUM(CASE WHEN pm_new = '0' OR pm_unread = '0' THEN 1 ELSE 0 END) AS old_pms
FROM bb3privmsgs_to
WHERE user_id='$user_id'
Here's a MySQL-specific version that reads more cleanly:
SELECT COUNT(IF(pm_new = '1' OR pm_unread = '1', 1, NULL)) AS new_pms,
COUNT(IF(pm_new = '0' OR pm_unread = '0', 1, NULL)) AS old_pms
FROM bb3privmsgs_to
WHERE user_id='$user_id'
MySQL will cast comparisons to 1 or 0. You can use SUM() to add up the portion of the WHERE clause you were trying to count results for.
This is a (MySQL specific) shorter alternative to the CASE WHEN examples.
SELECT
SUM(pm_new='1' OR pm_unread='1') as new_pms,
SUM(pm_new='0' OR pm_unread='0') as old_pms
FROM bb3privmsgs_to
WHERE user_id='$userid'
In SQL Server, you can do something like this:
SELECT
SUM(CASE WHEN pm_new='1' OR pm_unread='1' THEN 1 ELSE 0 END),
SUM(CASE WHEN pm_new='0' OR pm_unread='0' THEN 1 ELSE 0 END)
FROM
bb3privmsgs_to WHERE user_id='$user_id'
I'll suppose you can do about the same thing in mySql, let me get back to you on the details...
As a lazy alternative to some of the other suggestions:
SELECT SUM(newPMS) AS newPMS,
SUM(oldPMS) AS oldPMS
FROM ( SELECT COUNT(author_id) AS newPMS,
0 AS oldPMS
FROM bb3privmsgs_to
WHERE user_id='$user_id'
AND (pm_new='1' OR pm_unread='1')
UNION
SELECT 0 AS newPMS
COUNT(author_id) AS oldPMS
FROM bb3privmsgs_to
WHERE user_id='$user_id'
AND (pm_new='0' OR pm_unread='0')
)