Zend_Db_Select Select values not in specific table - php

I've googled my question and read through a bunch of forum posts but I've yet to find the answer I'm looking for hopefully someone here can help me out.
For a project I'm building I've set up the following 3 tables; users, projects and projectUsers.
I've set up a form where I can add users to projects by saving the userID and the projectID in the projectUsers table nothing special so far. The form contains a select element with userIDs that can be connected to a projectID (hidden field).
This form element is filled with a query set up with Zend_Db_Select it selects all the users from the users table and adds it to the select. However I want to filter that result so it excludes all of the users already added to that specific project.
Short version: I have a select element with users filled with a resultset from a (Zend_db_select) database query I want that resultset to be stripped from certain userIDs.
For extra reference the table scheme below:
CREATE TABLE IF NOT EXISTS `projects` (
`projectID` int(11) NOT NULL AUTO_INCREMENT,
`projectName` varchar(255) NOT NULL
PRIMARY KEY (`projectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `projectUsers` (
`projectUserID` int(11) NOT NULL AUTO_INCREMENT,
`projectID` int(11) NOT NULL,
`userID` int(11) NOT NULL
PRIMARY KEY (`projectUserID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `users` (
`userID` int(11) NOT NULL AUTO_INCREMENT,
`userFirstName` varchar(255) DEFAULT NULL,
`userLastName` varchar(255) DEFAULT NULL
PRIMARY KEY (`userID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Thanks in advance!

addint to Soica Micea ans
$blackList = array(1,3,5,6); //user id which you want to exclude
$db->select()->from('users', '*')
->joinLeft('projectUsers', 'projectUsers.projectUserID = users.userID', null)
->where('projectUsers.projectID = ?', someProjectID)
->where('projectUserID is null')
->where('users.userID not in (?)', implode(',',$blackList))
->query()->fetchAll();

This will select all users that have not been added to a project and ignore users from arrayOfUserIds
select()->from('users', '*')
->joinLeft('projectUsers', 'projectUsers.projectUserID = users.userID', null)
->where('projectUsers.projectID = ?', someProjectID)
->where('projectUserID is null')
->where('users.userID not in (?)', arrayOfUserIds)
->query()->fetchAll();

Related

Grocery relation sql databases

I use grocery-crud for a simple SQL select
$crud->set_table('lista_ab');
$crud->set_relation('id_ab','lista_ab_term','Expire');
The problem is that it does not make the relation for 'id_ab'
My database looks
CREATE TABLE `lista_ab` (
`id_ab` int(10) NOT NULL,
`Subname` varchar(255) DEFAULT NULL,
`Name` varchar(255) DEFAULT NULL,
`Inregistrat` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `lista_ab_term` (
`ID` int(10) NOT NULL,
`id_ab` int(10) DEFAULT NULL,
`Expire` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
In final I want to extract Subname and Expire.
You cannot create dropdown list and show field name of the first table : Subname, but you can have as many fields you like to call from the other table and the syntax is really simple.
Just at the 3rd field you will have the symbol { and } . So it will be for example:
$crud->set_relation('id_ab','lista_ab_term','{Expire} - {ID}');
You can use join query like this for your expected results:
SELECT t1.Subname, t2.Expire FROM lista_ab t1 LEFT JOIN lista_ab_term t2 ON t1.id_ab = t2.id_ab
Or In Codeigniter
$this->db->select('lista_ab.Subname,
lista_ab_term.Expire');
$this->db->from('lista_ab');
$this->db->join('lista_ab_term', 'lista_ab.id_ab= lista_ab_term.id_ab');
$q = $this->db->get();

How do I query the latest save progress of a list of users. (php/html)

I have a register and login site where people can click save progress on a form and it inserts a new row with their session id in column 2 as (user_id).
I also have an admin login where I can see their entries but it shows a list all their saves.
I wonder if you could help me figure out a query to list all the latest save progresses of each unique person? like (id,user_id,name,score): (3,3,bob, score 5) (6,4,sam, score 30) without showing all saves of a user's past saves like:
(1,3,bob, score 5) (2,4,sam, score 30) (3,3,bob, score 5) (4,4,sam, score 30)
I need the latest save of each user.
Like the latest id of a distinct list of user_id. Hope this makes sense. Thanks!
select user_id,name,score from your_table where (user_id,id) in (select user_id,max(id) from your_table group by user_id)
Considering the below formats for your tables
CREATE TABLE IF NOT EXISTS `user` (`user_id` int(11) NOT NULL auto_increment,
`user_name` varchar(200) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `user_score` (
`id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL,
`user_score` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1;
Please try executing the below sql select query for retrieving latest score for each user
SELECT u . * ,s.user_score,s.id FROM user u JOIN user_score s ON u.user_id = s.user_id WHERE id IN (SELECT MAX( id ) FROM user_score GROUP BY user_id)

Database structure for tags system

I'm making a simple PHP Forum, whereby tags are created alongside the main topic.
The table looks like this:
CREATE TABLE IF NOT EXISTS `topic` (
`topic_id ` int(100) NOT NULL AUTO_INCREMENT,
`topic_head` varchar(5) NOT NULL,
`topic_body` varchar(20) NOT NULL,
`topic_tag` varchar(20) NOT NULL,
`topic_date` varchar(20) NOT NULL,
`topic_owner` varchar(20) NOT NULL,
PRIMARY KEY (`topic_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
Specifically for the tags, I'll be performing a select query in the form of:
$tags = mysql_query("SELECT DISTINCT topic_tags
FROM forum_topics")
while($tags = mysql_fetch_assoc($tags){
$split_tags = "$tags";
$pieces = explode(",", $split_tags);
Currently, topic_tags are in the format tag1,tag2,tag3,tag4
How can I have it in such a way that each topic tag will be associated with each topic?
If I've understood correctly, what you want is another table for tags and then a third table to store the relationships. So:
CREATE TABLE `tags` (
`t_id` int(11) NOT NULL AUTO_INCREMENT,
`t_text` varchar(150) NOT NULL,
`t_datetime` datetime NOT NULL,
PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE `tag_pairs` (
`tp_id` int(11) NOT NULL AUTO_INCREMENT,
`tp_topic_id` int(11) NOT NULL,
`tp_tag_id` int(11) NOT NULL,
`tp_datetime` datetime NOT NULL,
PRIMARY KEY (`tp_id`),
FOREIGN KEY (`tp_topic_id`) REFERENCES topic('topic_id'),
FOREIGN KEY (`tp_tag_id`) REFERENCES tags('t_id')
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Then, to get tags for a topic based on its ID ($THIS_ID):
$query = mysql_query("
SELECT tags.t_text
FROM tags, tag_pairs, topic
WHERE topic.topic_id = '$THIS_ID'
AND tag_pairs.tp_topic_id = topic.topic_id
AND tag_pairs.tp_tag_id = tags.t_id
");
Call the columns just: id, head, body, tag_id (FK), date and user_id (FK)
This is much more understandable and also easier to use. Let me explain:
Right now you are using the columns as: topic_id, but it should be: topic.id. How do you get this? By simply using the tablename + column. So when the table is called topics and you have a column called id, you can use it by saying: topics.id. In the answer above from da5id, I can see that he is using topics.topic_id, a bit overkill isn't it? ;)
Also, read this article about database normal form 3 and google a bit yourself with database+3nf

MySQL + CodeIgniter + Click Tracking Unique & Total CLicks

Trying to track outbound clicks on advertisements, but im having troubles constructing the query to compile all the statistics for the user to view and track.
I have two tables, one to hold all of the advertisements, the other to track clicks and basic details on the user. ip address, timestamp, user agent.
I need to pull all of map_advertisements information along with Unique Clicks based on IP Address, and Total Clicks based on map_advertisements.id to be showin in a table with rows. 1 row per advertisement and two of its columns will be totalClicks and totalUniqueClicks
Aside from running three seperate queries for each advertisement is there a better way to go about this?
I am using MySQL5 PHP 5.3 and CodeIgniter 2.1
#example of an advertisements id
$aid = 13;
SELECT
*
count(acl.aid)
count(acl.DISTINCT(ip_address))
FROM
map_advertisements a
LEFT JOIN map_advertisements_click_log acl ON a.id = acl.aid
WHERE
a.id = $aid;
map_advertisements
-- ----------------------------
-- Table structure for `map_advertisements`
-- ----------------------------
DROP TABLE IF EXISTS `map_advertisements`;
CREATE TABLE `map_advertisements` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`youtube_id` varchar(255) NOT NULL,
`status` int(11) NOT NULL DEFAULT '1',
`timestamp` int(11) NOT NULL,
`type` enum('video','picture') NOT NULL DEFAULT 'video',
`filename` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`description` varchar(64) NOT NULL,
`title` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
map_advertisements_click_log
-- ----------------------------
-- Table structure for `map_advertisements_click_log`
-- ----------------------------
DROP TABLE IF EXISTS `map_advertisements_click_log`;
CREATE TABLE `map_advertisements_click_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`aid` int(11) NOT NULL,
`ip_address` varchar(15) NOT NULL DEFAULT '',
`browser` varchar(255) NOT NULL,
`timestamp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=latin1;
A problem seems to be in your query there is no column with the name totalClicks in your table and distinct keyword is also used incorrectly. Try this:
SELECT *, count(acl.id) as totalClicks, count(DISTINCT acl.ip_address) as uniqueClicks
FROM map_advertisements a
LEFT JOIN map_advertisements_click_log acl ON a.id = acl.aid
WHERE a.id = $aid;

How do I log in and display information from two tables (MySQL)?

I'm new to MySQL and PHP so Im not sure how to approach this problem I'm having.
I have two tables right now.
CREATE TABLE `users` (
`userid` int(25) NOT NULL AUTO_INCREMENT,
`username` varchar(65) NOT NULL DEFAULT '',
`password` varchar(32) NOT NULL DEFAULT '',
`emailaddress` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`userid`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
and
CREATE TABLE `images` (
`userid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`image` blob,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
so what I want to do is when a user signs in I want to be able to display an image that the user uploaded.
do I have to do something to the tables to make theme reference from each other?
help please!
Do you want just?...
select image from images
left join users on users.userid=images.userid
where username='whateverusername';
in the second table , the attribute userid should be a foreign key (i'd rather use Innodb to make sure that there is a foreign key constraint but it's up to u to use innodb or not)
so your table should look like this
CREATE TABLE images ( userid int(10) unsigned NOT NULL, name
varchar(50) DEFAULT NULL, image blob, foreign key userid
references users(userid) on delete cascade ) ENGINE=InnoDB
AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
once you do that, the table images will be linked to the table users which means that no record will be added to the table images unless the user id is already in the table users
if you wanna grab all the informations about that users including the image , you can perform a join between the two tables.
example with php
$con = mysql_connect("localhost","mysql_user","mysql_pwd");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
$user_id = 1;
$results = array();
> $results =mysql_query("select t1.userid,t1.username,t2.name,t2.image from users as t1 left join images as t2 on t1.userid=t2.userid where userid = $user_id",$con);
UPDATE:
make sure that the type of userid in both tables match

Categories