Using mysql how do you count the number of successfull ORs? - php

I basically want to count the number of ors that are successful so that I can tell the relevance of each item to the search query. This is the table structure:
CREATE TABLE `items` (
`id` int(11) NOT NULL auto_increment,
`listing_id` int(11) NOT NULL,
`name` varchar(256) NOT NULL,
`description` varchar(1000) NOT NULL,
`image` varchar(100) NOT NULL,
`image_caption` varchar(100) NOT NULL,
`keywords` varchar(10000) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=90 DEFAULT CHARSET=latin1
and this is an example of a row:
`id` = 1
`listing_id` = 1,
`name` = 'listing test',
`description` = 'listing desc',
`image` = '',
`image_caption` = '',
`keywords` = 'youtube video fun'
And this is what I want the mysql to do in pseudo code:
SELECT id,name,description AND count FROM items WHERE `keywords` LIKE '%video%' AND LIKE '%keyword2%' AND LIKE '%youtube%' AND LIKE '%text%'
And I want to get these results:
`id` = 1
`name` = 'listing test',
`description` = 'listing desc',
`count` = 2

Something like this. (I used "score" instead of "count" because "count" is a SQL function name.)
SELECT id, name, description, (
IF(keywords LIKE '%video%', 1, 0)
+ IF(keywords LIKE '%keyword2%', 1, 0)
+ IF(keywords LIKE '%keyword3%', 1, 0)
) score
FROM table
HAVING score > 0
Note that this query will be quite slow, as it must examine every row.

Related

Reduce MySQL request time with Codeigniter

I use Codeigniter 3.1.11 and have some code which makes one big query to MySQL with an array. The time of a query with a limit of 30000 is about 9 seconds.
How can I reduce the request time? Maybe by using some indexes on my table, or do you know another method? If I need to use indexes, what indexes would I need to use and how can I use these indexes in my query on Codeigniter?
Code from model:
function rows_update() {
$query = $this->db->order_by('rating', 'DESC')->get_where('members', 'game_rating_and_balance_update_last_time <= now() - INTERVAL 1 DAY', '30000', '0');
$arrUpdateBatchData = [];
while ($row = $query->unbuffered_row('array'))
{
// some code here
$arrUpdateData = [
'UserID' => $row['UserID'],
'game_vault_balance' => $new_game_vault_balance,
'game_available_balance' => $new_game_available_balance,
'rating' => $rating_member,
'game_rating_and_balance_update_last_time' => date('Y-m-d H:i:s')
];
$arrUpdateBatchData[] = $arrUpdateData;
if (count($arrUpdateBatchData) > 500)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
}
//update last items
if (count($arrUpdateBatchData) > 0)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
return;
}
Raw query to MySQL with update_batch (I simply write only one row from an array):
UPDATE members SET game_vault_balance = CASE WHEN UserID = '9915075' THEN 803.60516004772 ELSE game_vault_balance END, game_available_balance = CASE WHEN UserID = '9915075' THEN 4.1253850908788 ELSE game_available_balance END, rating = CASE WHEN UserID = '9915075' THEN 0.24 ELSE rating END, game_rating_and_balance_update_last_time = CASE WHEN UserID = '9915075' THEN '2020-07-24 22:00:36' ELSE game_rating_and_balance_update_last_time END WHERE UserID IN('9915075')
Table structure:
CREATE TABLE `members` (
`id` int(10) UNSIGNED NOT NULL,
`UserID` varchar(64) NOT NULL,
`telegram_id` varchar(64) DEFAULT NULL,
`first_name` varchar(64) DEFAULT NULL,
`last_name` varchar(64) DEFAULT NULL,
`language` varchar(64) DEFAULT NULL,
`currency` varchar(64) DEFAULT NULL,
`status` varchar(64) DEFAULT NULL,
`rating` varchar(64) DEFAULT NULL,
`game_vault_balance` decimal(32,8) DEFAULT 0.00000000,
`game_available_balance` decimal(32,8) DEFAULT 0.00000000,
`game_rating_and_balance_update_last_time` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
`created` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Indexes of this table:
ALTER TABLE `members`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `UserID` (`UserID`) USING BTREE;
AUTO_INCREMENT for the members table:
ALTER TABLE `members`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;

MySQL query not returning any results even though data exists in database

Why is this query not showing more than one data. Even I have 10/12 data but this line only shows 1. Check I have limited it to 3 but it only shows 1.
$getAds = mysql_query("SELECT *
FROM advertises
WHERE status='RUNNING'
AND adult='0'
AND (country LIKE '%$test%' OR country='ALL')
AND (device LIKE '%$pabu%' OR device='ALL')
ORDER BY rand()
LIMIT 0,3");
my database structure
Table structure for table advertises --
CREATE TABLE `advertises` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) NOT NULL, `name` varchar(5000) NOT NULL, `url` varchar(5000) NOT NULL, `type` varchar(500) NOT NULL, `device` varchar(500) NOT NULL, `country` varchar(500) NOT NULL, `time` varchar(500) NOT NULL, `status` varchar(500) NOT NULL, `dset` varchar(500) NOT NULL, `cset` varchar(500) NOT NULL, `acpc` varchar(500) NOT NULL, `ucpc` varchar(500) NOT NULL, `adult` tinyint(10) unsigned NOT NULL DEFAULT '0', `title` varchar(500) NOT NULL, `pcpc` varchar(500) NOT NULL DEFAULT '0', `spent` varchar(500) NOT NULL DEFAULT '0', `adc` varchar(500) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
------ -- -- Dumping data for table advertises --
INSERT INTO `advertises` VALUES ('1','1','dqui.com/adultb.php','lt.adqui.com','banner','ALL','ALL','Saturday , September 19 , 2015','RUNNING','no','no','0.015','0.012','1','Android Adult','0.005','49999.925',''); INSERT INTO `advertises` VALUES ('2','1','http://adqui.com/banner.php','http://kid.adqui.com','banner','ALL','ALL','Saturday , September 19 , 2015','RUNNING','no','no','0.01','0.008','0','Android Non','0.002','49999.88','');
INSERT INTO `advertises` VALUES ('3','1','qui.com/adultb.php','lt.adqui.com','banner','ALL','ALL','Saturday , September 19 , 2015','RUNNING','no','no','0.0002','0.0002','1','Adult','0.00','4999.874','0.0002'); INSERT INTO `advertises` VALUES ('4','1','adqu i.com/banner.php','kid.adq ui.com','banner','ALL','ALL','Saturday , September 19 , 2015','RUNNING','no','no','0.0002','0.002','0','non','','4999.923','0.0008');
Status is a keyword in mysql. so try this
$getAds=mysql_query("SELECT * FROM advertises WHERE `status`='RUNNING' AND adult='0' AND (country LIKE '%test%' OR country='ALL') AND (device LIKE '%pabu%' OR device='ALL') ORDER BY rand() LIMIT 0,3");
Have you tried to use mysql_fetch_assoc on the result returned by mysql_query?
Refer to the mysql-query manual in particular Example #2
mysql_query() has already been deprecated, you can use PDO instead.
Try below,
<?php
$dbcon = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$test = 'All';
$pabu = 'All';
$qry = "SELECT *
FROM advertises
WHERE status='RUNNING'
AND adult='0'
AND (country LIKE '%$test%' OR country='ALL')
AND (device LIKE '%$pabu%' OR device='ALL')
ORDER BY rand()
LIMIT 0,3";
$rq = $dbcon->query($qry);
$op = ( $rq ) ? $rq->fetchAll(PDO::FETCH_ASSOC) : '';
echo '<pre>'; print_r($op);
?>

Select two columns from two tables and order by their values DESC

With this code I'm getting news from the database and order it by column "views":
<?php
$getnewsinfo = mysql_query("SELECT * FROM news ORDER BY views DESC LIMIT 5");
while($newsinforow = mysql_fetch_array($getnewsinfo))
{
$newsid = $newsinforow['id'];
$title = $newsinforow['title'];
$author = $newsinforow['author'];
$date = date('d.m.Y', $newsinforow['date']);
$picture = $newsinforow['picture'];
$picture_desc = $newsinforow['picture_desc'];
$category = $newsinforow['category'];
$text = $newsinforow['text'];
?>
Now I want to order the news by views and by the number of comments, but I have no idea how.
Here is my database structure :
CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) NOT NULL auto_increment,
`views` int(11) NOT NULL default '0',
`title` varchar(255) NOT NULL,
`author` varchar(255) NOT NULL,
`date` varchar(255) NOT NULL,
`picture` varchar(255) NOT NULL,
`picture_desc` varchar(255) NOT NULL,
`category` varchar(255) NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `news_comments` (
`id` int(11) NOT NULL auto_increment,
`news_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`website` varchar(255) NOT NULL,
`text` text NOT NULL,
`date` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
I also want to ask you... do you have any comments on the code and database structure ?
Try this sql
SELECT n.*,count(nc.id) as cnt FROM news as n, news_comments as nc where n.id = nc.news_id group by nc.news_id ORDER BY views DESC,cnt DESC LIMIT 5

PHP/MYSQL - Which Join Statement To Use To Simplify My Queries?

I have these 2 queries and i would like to join them into one but i am unsure of how to go about it.
Query 1:
$query = "SELECT * FROM ".$db_tbl_comics." WHERE ".$db_fld_comics_publisher."='".$pub_id."'
AND ".$db_fld_comics_active."='1' GROUP BY ".$db_fld_comics_arc;
Query 2:
$q2 = mysql_query('SELECT '.$db_fld_arcs_title.' FROM '.$db_tbl_arcs.'
WHERE '.$db_fld_arcs_id.'="'.$result[$db_fld_comics_arc].'"');
Comics Table:
CREATE TABLE IF NOT EXISTS `comics` (
`id` varchar(255) NOT NULL,
`arc` int(255) NOT NULL,
`title` varchar(255) NOT NULL,
`issue` decimal(5,1) DEFAULT NULL,
`price` decimal(10,2) NOT NULL,
`plot` longtext NOT NULL,
`publisher` int(255) NOT NULL,
`isbn` varchar(255) NOT NULL,
`published` date NOT NULL,
`cover` varchar(255) NOT NULL DEFAULT './images/nopic.jpg',
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`views` int(255) NOT NULL DEFAULT '0',
`active` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `arc` (`arc`,`title`,`issue`,`publisher`)
);
Arcs Table:
CREATE TABLE IF NOT EXISTS `arcs` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`plot` longtext NOT NULL,
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`)
);
What I need to do is get the Arcs Title from the arcs table for the respective comic arc.
You need to use INNER JOIN for that since I presume that records are present on both tables.
SELECT a.*, b.title
FROM comics a INNER JOIN arcs b
on a.id = b.id
WHERE a.Title = 'VALUEHERE'
displays all details from comics table and the title of the arc
as simple as (joining 2 queries in one, by selecting only the required field and using IN):
SELECT
'.$db_fld_arcs_title.'
FROM '.$db_tbl_arcs.'
WHERE '.$db_fld_arcs_id.' IN (
SELECT '.$db_fld_comics_arc.'
FROM '.$db_tbl_comics.'
WHERE '.$db_fld_comics_publisher.'='".$pub_id."'
AND '.$db_fld_comics_active.'='1' GROUP BY '.$db_fld_comics_arc.'
)

Show proper categories for blogposts

I'm trying to get all the categories about the specific blogpost but it will not work as I wanted it to work. Below you can see the SQL and code. $blog fetch the information about the specific blogpost.
CREATE TABLE IF NOT EXISTS `blogposts` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`id_user_created` int(10) DEFAULT '0',
`id_user_edited` int(10) DEFAULT '0',
`post_subject` varchar(100) NOT NULL,
`post_message` text NOT NULL,
`post_categories` text NOT NULL,
`date_published` datetime NOT NULL,
`date_edited` datetime NOT NULL,
`info_ipaddress_created` text NOT NULL,
`info_ipaddress_edited` text NOT NULL,
`is_shared` enum('0','1') DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`id_user` int(10) DEFAULT '0',
`post_name` text NOT NULL,
`date_added` datetime NOT NULL,
`date_edited` datetime NOT NULL,
`info_ipaddress` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
$get_categories = "SELECT * FROM blogposts, categories
WHERE blogposts.id = '".(int)$blog['id']."'
AND blogposts.post_categories = categories.id
";
foreach($sql->query($get_categories) AS $category) {
echo '<a href="'.url('blog/category/'.$category['post_name']).'" class="grey-link">';
echo $category['post_name'];
echo '</a>';
}
INSERT INTO blogposts` (id, id_user_created, id_user_edited, post_subject, post_message, post_categories, date_published, date_edited, info_ipaddress_created, info_ipaddress_edited, is_shared)
VALUES (1, 1, 1, 'test', 'testar', '1', '', '', '', '', '0'),
(2, 1, 1, 'med kategorier', 'wiho!', '1|2', '', '', '', '', '0');
INSERT INTO categories` (id, id_user, post_name, date_added, date_edited, info_ipaddress)
VALUES (1, 1, 'test', '', '', ''),
(2, 1, 'test2', '', '', '');
Right now it's only prints Categorized in test, on both blogposts I have posted. It should prints out Categorized in test for the first post and Categorized in test, test2 for the second post. post_categories looks like this: 1|2 which is the ID for the specific category.
Thanks in advance.
If I look at your 'blogposts' table, your 'post_categories' field is of type text. I don't know what is in there but I can imagine it to be a string with id's separated by some character like a semi-colon. This approach limit's the flexibility of your queryies. You'd be better of by creating a link table. This means that you introduce a new table that is responsible for the linkage between a blogpost and it's categories. Looking something like:
CREATE TABLE IF NOT EXISTS `blogposts` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`post_message` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`category_name` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `post_categories` (
`post_id` int(10) NOT NULL AUTO_INCREMENT,
`category_id` text NOT NULL
)
This last table can be used to get all categories that come with a blogpost. You can query over it by using a JOIN, like so:
SELECT *
FROM blogposts b
INNER JOIN post_categories pc ON pc.post_id=p.id
INNER JOIN categories c ON c.id=pc.category_id
WHERE b.id=<yourvariable>
You will than have a list with a lot of duplication but each row is for another category which you can use to display somewhere or whatever purpose you have with it. Maybe it is cleaner to separate this into two queries that a. get the blogpost with the id you have and b. get the categories that come with the blogpost by using the link table.

Categories