Hello i am trying to retrieve a list of records from my database and table using two criterias and the data has to be combined as one
the first statement which i have written is
FROM `transactions` WHERE `Start_Date` = '$_POST[start]' AND `Company` = '$_POST[star]' and Status = ''
this statement all the records which has its column as empty,
now i want to also capture together with this data all columns that have status as successful
FROM `transactions` WHERE `Start_Date` = '$_POST[start]' AND `Company` = '$_POST[star]' and Status = 'successful'
please how do i combine this, i initially tried this
FROM transactions WHERE Start_Date = '$_POST[start]' AND Company = '$_POST[star]' and Status = '' and (status = 'successful')
i thought it should work but it dosent seem to work, any help please on the correct way
Each row in your table will be evaluated individually to see if it meets the criteria defined in the WHERE clause. Since you need to check for two possible values in the same column, and one row cannot have two different values for the same column, you'll need to use OR instead of AND.
WHERE
`Start_Date` = '$_POST[start]'
AND `Company` = '$_POST[star]'
AND (`Status` = '' OR `Status` = 'successful')
The effect of this will be like combining your two queries. You'll get all rows that meet the Start_date and Company criteria as well as having either Status = '' or Status = 'successful'.
You can use "IN" operator to achieve this.
FROM 'transactions'
WHERE 'Start_Date' = '$_POST[start]' AND 'Company' = '$_POST[star]' AND
Status IN ('','successful')
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am checking the for the user_id (it is held in a session) - this is working. Then I am running a SELECT query for that user for the database table click_count. I am checking to see if that user has any records within it, ie: $page_count. If not, I want my INSERT statement to run to add that user to the database table along with other data.
The part I do not understand is it seems that my UPDATE query is always running. For example no matter which user I login with my query only updates the only user in the database table. IE: Bob is the only user in the click_count table, if I log in with Pete, Bob's record is being updated.
I have tested the value for $page_count and it equals 0, so my INSERT should be running. I have also tried if ($page_count === 0) {
Does anyone see anything I am missing?
$curPage = $_SERVER['PHP_SELF'];
$clicks = 0;
$setup = 0;
$page_total_count = 0;
var_dump($user_id);
$click_sql = "
SELECT *
FROM click_count
WHERE user_id = ?
AND page_url = ?
";
$click_stmt = $con->prepare($click_sql);
$click_stmt->execute(array($user_id, $curPage));
$click_stmt_rows = $click_stmt->fetchAll(PDO::FETCH_ASSOC);
$page_count = $click_stmt->rowCount();
foreach ($click_stmt_rows as $click_stmt_row) {
$setup_status = $click_stmt_row['setup'];
$page_total_count = $click_stmt_row['page_count'];
}
if ($page_count == 0) {
$click_insert_sql = "
INSERT INTO click_count
(user_id, page_url, page_count, setup)
VALUES(?, ?, ?, ?)
ON DUPLICATE KEY UPDATE page_count=page_count+1;
";
$click_insert_stmt = $con->prepare($click_insert_sql);
$click_insert_stmt->execute(array($user_id, $curPage, 1, $setup));
}
else {
$click_update_sql = "
UPDATE click_count
SET page_count=page_count+1
WHERE user_id = ?
AND page_url = ?
";
$click_update_stmt = $con->prepare($click_update_sql);
$click_update_stmt->execute(array($user_id, $curPage));
}
Table
click_count
CREATE TABLE `click_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`page_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`page_count` int(11) NOT NULL,
`setup` int(5) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`),
UNIQUE KEY `page_url` (`page_url`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Since there is only the one user in the table, there is no record "to insert/update", therefore
ON DUPLICATE KEY UPDATE failed you silently.
A regular UPDATE will suffice:
I.e. and as an example:
UPDATE table SET col_x = 0|1 WHERE col_y = ? // (boolean 0-1)
Note:
If ever you wish to increase a column by counting later on, the syntax would be:
UPDATE table SET col_x = col_x + 1 WHERE col_y = ?
In regards to your asking about how you could improve on your code:
#Fred-ii- Thanks. Yes, it is working now how I want, but if there are ways to improve the code I am always willing to try to learn it. I just remembered people in the past saying that I didn't need the update query at all with the duplicate key update. – Paul
You could use named placeholders :name rather than ? since they are easier to keep track of, but this is of course a matter of opinion that I feel is also shared by many and not just myself.
Footnotes/credits:
I would like to also give credit to the following comment:
"If you always fall into update indicates that $page_count is not zero.. Try to echo() it to see maybe.. I would probably first try to add another user into click_count table and then it may become easier to see where it goes wrong.. – johnyTee"
where the OP responded with:
"#Fred-ii- I figured it out. I used johnyTee's advise and tried adding another user to the database manually and it wouldn't let me because of the unique index for the page_url column. I then removed the unique index from it and now it works perfectly. Thanks for the help! – Paul"
from PHP PDO doc http://php.net/manual/en/pdostatement.rowcount.php
PDOStatement::rowCount() returns the number of rows affected by a
DELETE, INSERT, or UPDATE statement.
if you need th number of rows in select you should use somethings like
$sql = "SELECT *
FROM click_count
WHERE user_id = ?
AND page_url = ?
";
$result = $con->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
It may be '0' (a string). You can use intval to convert it to an integer.
$page_count = intval( $click_stmt->rowCount() );
http://php.net/manual/en/function.intval.php
For most databases, PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement. Instead, use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned. Your application can then perform the correct action.
try like this:
$sql = "SELECT count(*)
FROM click_count
WHERE user_id = ?
AND page_url = ?
";
if ($res = $conn->query($sql)) {
/* Check the number of rows that match the SELECT statement */
if ($res->fetchColumn() > 0) {
//insert
}else {
//update
}
}
i have an c++ program that sending POST of logs to my server and store it on database, the problem is that the checking of duplicates before insert a new row is not working, i think that the program send the POST very fast and there is no delay between the POSTS to the server so the Mysqli can't handle this, is there any solution from server client? maybe locking rows or something?
$date = date('Y-m-d', time());
$prep_select_qa = 'SELECT * from `logs` WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?';
$select_qa = $db->prepare($prep_select_qa);
$select_qa->bind_param('sss', $_POST['guid'], $_POST['error_code'], $date);
$select_qa->execute();
$select_qa->store_result();
$num_rows = $select_qa->num_rows;
if($num_rows == 0)
{
$prep_insert_qa = 'INSERT INTO `logs` (`type`, `guid`, `sent_by`, `class_and_method`, `api_method`, `error_code`, `error_text`, `date_create`) VALUES (?,?,?,?,?,?,?,?)';
$insert_qa = $db->prepare($prep_insert_qa);
$insert_qa->bind_param('ssssssss', $new, $_POST['guid'], $_POST['sentBy'], $_POST['classAndMethodName'], $_POST['APImethod'], $_POST['ErrorCode'], $_POST['ErrorText'], $date);
$insert_qa->execute();
$insert_qa->store_result();
}
First, the answer to your question is that you are retrieving all the rows in order to count them. Presumably, this requires reading all the data in the table and returning some of it (unless you have indexes). A faster method is to check the value returned by this query:
SELECT count(*)
FROM `logs`
WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?';
And an even faster method is not to count but to determine if any row exists:
SELECT EXISTS (SELECT 1
FROM `logs`
WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?'
)
This will return 1 if the row exists and 0 otherwise. Both of the above queries and your original query will benefit from having an index on guid, error_code, date_create.
In practice, you should follow Marvin's advice and use a unique index. This means the database does the checking via a unique index rather than the application. One very important reason is a race condition. If two users are inserting the same row at the same time, both might execute the if statement, find there are no matching rows in the table, and then insert duplicate rows.
The SELECT scheme must be enclosed in a BEGIN...COMMIT transaction and have FOR UPDATE on it. Otherwise, some other connection can slip in and defeat your check.
Instead, try to do it in a single, atomic, instruction:
Once you have an INDEX that will prevent duplicates...
INSERT IGNORE -- Silently does nothing if it is a dup.
INSERT...ON DUPLICATE KEY UPDATE -- Lets you change something as you try to insert a dup.
Also, the INSERT solutions will be faster (which was your original question).
I have a problem with mysql query. for a cuople days I cannot solve it.
URL params ?a=1&b=2&c=3
Structure:
attr_id
value_id
query:
SELECT DISTINCT `product_id`
FROM `products_attr_val`
WHERE
(`attr_id` = '".$searchqueryArray2[0]."' AND `value_id` = '".$searchqueryArray2[1]."')
OR (`attr_id` = '".$searchqueryArray2[0]."' AND `value_id` = '".$searchqueryArray2[1]."')
but the problem is that if a=12&b=10
and if there is a product with atribute 10 or atribute 12 it shows. I need to show products with a=12 and b=10.
Whats wrong?
Thanks for help.
Sounds like you need to use GROUP BY and HAVING clauses.
SELECT
`product_id`,
COUNT (`primary_key_id`) AS `attr_count` /* primary key field here */
FROM `products_attr_val`
WHERE
(`attr_id` = ? AND `value_id` = ?)
OR (`attr_id` = ? AND `value_id` = ?)
/* additional as necessary
OR (`attr_id` = ? AND `value_id` = ?)
*/
GROUP BY `product_id`
HAVING `attr_count` = ? /* value here should be equal to number of attributes you are checking for */
Make sure you have a unique index across product_id and attr_id for this to work properly (you should already have this since it would not likely make sense for a product to have multiple records with the same attr_id).
You also need to make sure you are escaping your values for use in your SQL if you are not already. I am showing these variables here with ? which, if you we using prepared statments, would be a way you might write this SQL.
i amn trying to run an insert query to insert the NOW() time and date only if certian enum values in my table are set to yes.
my table has 4 columns 'form1_completed', 'form2_completed', 'form3_completed', 'form4_completed'
the columns will be yes or no.
i am using this query to try and insert the current time and date into the database, its inserting but it doesnt pay attention to the where clause and just inserts anyway, can someone please show me what im doing wrong
$query2 = "IF (SELECT * FROM `supplier_session` WHERE `form1_completed` = 'Yes' AND `form2_completed` = 'Yes' AND `form3_completed` = 'Yes' AND `form4_completed` = 'Yes') INSERT INTO `supplier_session` (`completed_date`) VALUES (NOW());
WHERE `user_IP` = '$ipaddress '";
Instead of
WHERE `form1_completed` = Yes
use
WHERE `form1_completed` = 'Yes'
I think it should be:
IF EXISTS (SELECT * FROM ...) INSERT INTO ...
EXISTS (subquery) is true when the subquery returns any rows.
Or you could do:
IF (SELECT COUNT(*) FROM ...) INSERT INTO ...
is there a way to get default values of columns as they are a row of a resultset?
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`state` tinyint(2) NOT NULL DEFAULT '22',
`pubdate` datetime NOT NULL DEFAULT '2012-01-01 00:00:00',
for instance a table like this should return this record:
id->NULL (?)
state->22
pubdate->2012-01-01 00:00:00
in practice, when some user opens edit.php?id=44 he will get the row 44 (update mode), but if he opens edit.php?id=0 (insert mode) I want that the fields contain default values as place holders
thank you in advance
There is a DEFAULT function
SELECT DEFAULT( id ) , DEFAULT( EXAMPLE ) FROM test LIMIT 1
With above query, it seems that you need to have atleast one record in the table as it returns no records otherwise. For current timestamp, it return a timestamp formatted string of 0s.
Sure, using the information_schema database (which stores all the information about your database structure), you can do something like:
SELECT
COLUMN_NAME,
COLUMN_DEFAULT
TABLE_NAME
FROM information_schema.COLUMNS
WHERE
TABLE_NAME='your_table_name'
AND TABLE_SCHEMA='your_database_name'
If you have a limited number of columns, you can collect them into a row using a construct like:
SELECT
id.defaultval AS id_default,
state.defaultval AS state_default,
pubdate.defaultval AS pubdate_default
FROM
(SELECT TABLE_NAME, COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='id') id
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='state') state ON id.TABLE_NAME = state.TABLE_NAME
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='pubdate') pubdate ON id.TABLE_NAME = pubdate.TABLE_NAME
Use DESCRIBE http://dev.mysql.com/doc/refman/5.0/en/describe.html
DESCRIBE sometable [somefield]
Here is php example for single field:
$resource = mysql_query("DESCRIBE sometable somefield");
$schema = mysql_fetch_assoc($resource);
$default = $schema['default'];
And here is the php example for few fields:
$resource = mysql_query("DESCRIBE sometable");
while ($schema = mysql_fetch_assoc($resource)) {
$default_list[$schema['Field']] = $schema['Default'];
}
I see no use for such a behavior and find it wrong.
It is not convenient to use. Imagine I want to enter my own state value. I'd have to delete default 22 first.
Even worse with date. Instead of setting current datetime, you are going to make me edit whole date. Why?
And for the id it is just impossible.
Why can't you just check the input fields and if empty - not to insert at all, letting database set these defaults
You just overthinked it, I believe.