PHP and SQL Social Operations - php

I've got a table created using this query.
CREATE TABLE `tbl_friends` (
`friend_id` int(11) NOT NULL auto_increment,
`friend_status` tinyint(4) NOT NULL default '0',
`friend_id1` int(11) NOT NULL default '0',
`friend_id2` int(11) NOT NULL default '0',
`friend_date` datetime NOT NULL default '0000-00-00 00:00:00',
`friend_confirm` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`friend_id`)
) TYPE=MyISAM AUTO_INCREMENT=10 ;
I want to view the list of my friends, for that I only need to know other user's id - numeric value stored in friend_id1 or friend_id2 rows. My problem is that I don't know if friend_id1 or friend_id2 contains required data.
Please help me create a query to receive the number of another user if my number is $_SESSION['id']

CREATE TABLE `tbl_friends` (
`friend_id` int(11) NOT NULL auto_increment,
`friend_status` tinyint(4) NOT NULL default '0',
`friend_id1` int(11) NOT NULL default '0',
`friend_id2` int(11) NOT NULL default '0',
`friend_date` datetime NOT NULL default '0000-00-00 00:00:00',
`friend_confirm` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`friend_id`)
) TYPE=MyISAM AUTO_INCREMENT=10 ;
Would be like so:
SELECT * FROM tbl_friends WHERE friend_id2 = %d OR friend_id1 = %d AND friend_status != 0 ORDER BY friend_id
More Visual example:
SELECT
*
FROM
tbl_friends
WHERE
friend_id2 = %$1d
OR
friend_id1 = %$1d
AND
friend_status != 0
ORDER BY
friend_id
DESC
Then just run it threw a sprintf function and your ready.
$sql = sprintf($sql,$_SESSION['id']);

I'm not sure what you exactly mean, but I think your looking for something like:
select distinct * from tbl_friends where friend_id1 = $_SESSION["id"] OR friend_id2 = $_SESSION["id"];
If this is not what you mean, please add some additional information.

Something like:
Select distinct(id) from (
select friend_id1 as id from friends where friend_id2 = :my_id
union
select friend_id2 as id from friends where friend_id1 = :my_id
)
There real problem here is keeping the table from getting weird data. You are better off always putting two records into the table for each reciprocal relationship. Then you only need to say:
select * from friends where friend_id1 = :my_id and status = :whatever
If you do it this way, the control data for when friendship happens might need to move to another table

Related

CodeIgniter join string with !== mysql query to operation is not working and giving error

I have two tables:
Table 1:
CREATE TABLE `users` (
`user_id` int(255) NOT NULL,
`user_name` varchar(100) NOT NULL,
`user_email` varchar(100) NOT NULL,
`user_password` varchar(200) NOT NULL,
`user_phone` varchar(20) NOT NULL,
`building_units` int(200) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` enum('0','1') NOT NULL DEFAULT '1' COMMENT '1 = Active(default), 0 = Inactive',
`user_role` enum('0','1','2','3') NOT NULL DEFAULT '2' COMMENT '0=Manager,1=Admin,2=User,3=Tenant',
`user_ip` int(39) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Table 2:
CREATE TABLE `building_admins_tbl` (
`id` int(255) NOT NULL,
`building_id` int(255) NOT NULL COMMENT 'FK ',
`building_admin_id` int(255) DEFAULT NULL COMMENT 'FK',
`user_id` int(255) DEFAULT NULL,
`tenant_id` int(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And I have written the following query:
$select = 'users.user_id,users.user_name,users.user_role,users.status,building_admins_tbl.building_admin_id';
$join_str = 'users.user_id != building_admins_tbl.building_admin_id';
$where = ['users.user_role'=>'1','users.status'=>'1'];
$q =$this->db
->select($select)
->where($where)
->from('users')
->join('building_admins_tbl',$join_str)
->get();
$admin_list =$q->result_array();
In the above query the join string is important. I want to get only those rows where(users.user_id != building_admins_tbl.building_admin_id) with the where condition as well.
But I am not getting the expecting result. How can I fix this?
I'm not certain what you should be joining, because you haven't properly set up your foreign keys, and if you did you didn't include that information, but I'll give it a shot because the real answer is that you want to do the join, but use a different WHERE clause.
You must actually join the other table, and you can't use !=:
// This looks like you are trying to join on the admin ID, which is probably wrong
$join_str = 'users.user_id = building_admins_tbl.building_admin_id';
// If you are trying to get tenants, it's probably supposed to be:
$join_str = 'users.user_id = building_admins_tbl.tenant_id';
// If you are trying to join with the users table, it might be:
$join_str = 'users.user_id = building_admins_tbl.user_id';
But then make sure you aren't including admins
$where = [
'users.user_role !=' => '1', // Do not include user role #1 (admins)
'users.status' => '1'
];
after inserting just load your view page
and add these line in your view page
$this->output->enable_profiler(TRUE); //within php tag
these will give you raw query in your view just copy the query and execute it in phpmyadmin
I found the answer.
$q = $this->db
->from('users')
->where(['user_role'=>'1'])
->where(['status'=>'1'])
->where("
NOT EXISTS (
select building_admin_id from building_admins_tbl where users.user_id = building_admins_tbl.building_admin_id)")
->get();
$data['admins_list'] = $q->result_array();

How to Run Timely Automated Query on MySQL

I have a field called pending and been declared as Boolean with default value of 0 as:
`pending` tinyint(1) NOT NULL DEFAULT '0'
I am running an Update query againt the database to change the state of qpending to 1 like below
$sql = "UPDATE `appointments` SET `pending` = '1' WHERE `appointments`.`id` = 124;
now my question is, is there any way to automatically re-state the pending to 0 after 30 minutes by taking a conditional clause like
// After 30 Minutes of update!
if (!confirmed){
$sql = "UPDATE `appointments` SET `pending` = '0' WHERE `appointments`.`id` = 124;
}
Table Schema
CREATE TABLE IF NOT EXISTS `appointments` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`date` varchar(100) CHARACTER SET utf8 NOT NULL,
`available` tinyint(1) NOT NULL DEFAULT '1',
`pending` tinyint(1) NOT NULL DEFAULT '0',
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
You are doing it wrong.
Make your pending field not a boolean but a datetime, with the value of the due time. Then in your select queries just compare that value with the current time. So instead of
SELECT * FROM appointments WHERE pending = 1
just make it
SELECT * FROM appointments WHERE pending < NOW()
this solution is either much simpler and more flexible

How to select ONLY posts from friends and viewing user

I'm making a social plugin for my website, and I have a friends table that holds all accepted friend requests, and I need to display all posts from the users friend AND the users posts in order of the date, so I've tried this sql query:
SELECT DISTINCT `social_posts`.*, `social_friends`.*, `users`.*
FROM `social_posts`
JOIN `social_friends`
ON `fUID` = '1' AND `friend` = `pUID` OR `pUID` = '1'
JOIN `users`
ON `friend` = `uid`
ORDER BY `date` DESC
Structure
CREATE TABLE `social_friends` (
`fID` int(11) NOT NULL AUTO_INCREMENT,
`fUID` int(11) NOT NULL,
`friend` int(11) NOT NULL,
PRIMARY KEY (`fID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `social_posts` (
`pid` int(11) NOT NULL AUTO_INCREMENT,
`pUID` int(11) NOT NULL,
`body` text NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
fUID is the users (viewing) user ID, and friend is the users friend, and pUID is the user ID of the user who made the post.
But this shows two of each post, even with SELECT DISTINCT, and I'm out of ideas on how to figure this out.
1 - Can you give as more info (the fields) of the tables?
What is fUID and pUID
2 - Try and change
ON `fUID` = '1' AND `friend` = `pUID` OR `pUID` = '1'
to ON friend = pUID and put fUID = 1 OR pUID = 1 in the WHERE clause

Best way to count millions of rows between certain dates in MySQL

Here is my SQL for creating a table:
$sql_create_table = "CREATE TABLE {$table_name} (
hit_id bigint(20) unsigned NOT NULL auto_increment,
user_id int(7) unsigned NOT NULL default '0',
optin_id int(8) unsigned NOT NULL default '0',
hit_date datetime NOT NULL default '0000-00-00 00:00:00',
hit_type varchar(10) NOT NULL default '',
PRIMARY KEY (hit_id),
KEY user_id (user_id)
) $charset_collate; ";
I need to know the fastest way to count the number of rows within a query. My current query doesn't cut it for going through millions of rows.
$sql = "SELECT hit_id FROM $table_name WHERE user_id = %d AND hit_type = %s AND hit_date >= FROM_UNIXTIME(%d) AND hit_date <= FROM_UNIXTIME(%d)";
I've tried this with no luck (not returning the proper results):
$sql = "SELECT COUNT(*) FROM $table_name WHERE user_id = %d AND hit_type = %s AND hit_date >= FROM_UNIXTIME(%d) AND hit_date <= FROM_UNIXTIME(%d)";
What do I need to do to make this query efficient so that it doesnt time out for millions of rows? I simply want to count the number of rows within the specified parameter set.
I'm not sure of the performance of the FROM_UNIXTIME function, but the first thing I would do is create an index on hit_date.
http://dev.mysql.com/doc/refman/5.0/en/create-index.html

mysql - php - Need to get only the latest record from a self referencing data

Hi,
I need some help with SQL. Attached is the image of my table.
If you see rootmessageid column there are 4 records of 99s. All these 4 makes one complete conversation.
Similarly the 2 records of 119 makes an other conversation.
116, 117, 118 are single message conversation.
Now I need to get all the records where msgfrom = 7 or msgto = 7 (this was the easy part)
Now the complicated bit. I want the only the latest record (based on datetimecreated) from each conversation.
Following the script to create this table.
CREATE TABLE IF NOT EXISTS `selectioncommunication` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`comactionid` int(11) NOT NULL,
`usercomment` varchar(2048) DEFAULT NULL,
`msgfrom` int(11) NOT NULL,
`msgto` int(11) NOT NULL,
`projectid` int(11) NOT NULL,
`parentmessageid` int(11) NOT NULL,
`datetimecreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`rootmessageid` int(11) NOT NULL,
`isread` tinyint(1) NOT NULL DEFAULT '0',
`isclosed` tinyint(1) DEFAULT '0',
`relative_date_time` datetime DEFAULT NULL,
`consultant_response` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=121 );
You want the groupwise maximum:
SELECT s.*
FROM selectioncommunication s NATURAL JOIN (
SELECT parentmessageid, MAX(datetimecreated) datetimecreated
FROM selectioncommunication
WHERE msgfrom = 7 OR msgto = 7
GROUP BY parentmessageid
) t
WHERE s.msgfrom = 7 OR s.msgto = 7
use ORDER BY datetime ASC/DESC
this will sort your results in order then add LIMIT 1 to the end of your query to only get the first record in your list.
Here is your SQl Fiddle without Join
SELECT *
FROM selectioncommunication k
WHERE datetimecreated = (SELECT
MAX(datetimecreated)
FROM selectioncommunication s
WHERE s.rootmessageid = k.rootmessageid
GROUP BY s.rootmessageid
ORDER BY s.id)

Categories