Hollow i have kind of query for my table select m.voterID, sum(jm.mark) from marks m
left join marks jm on jm.id = m.id
where jm.voterID in (1,2)
group by m.voterID
and i don't understand how to wright it using the CDbCriteria.
table structute is
`id` int(11) NOT NULL AUTO_INCREMENT,
`voterId` int(11) NOT NULL,
`votedId` int(11) NOT NULL,
`mark` int(11) NOT NULL,
`creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
$criteria = new CDbCriteria();
$criteria->select = 'm.voterID, sum(jm.mark)';
$criteria->from = 'marks m';
$criteria->join = 'left join marks jm on jm.id = m.id';
$criteria->condition = 'jm.voterID in (1,2)';
$criteria->group = 'm.voterID';
Related
I'm trying to find all the values where empresas.id = (a number);
Here's my query:
SELECT empresas.nome, departamentos.nomeDepartamento,
funcionarios.nomeFuncionario, funcionarios.email, funcionarios.idFuncionario FROM empresas
INNER JOIN departamentos ON empresas.id = departamentos.idEmpresas
INNER JOIN funcionarios ON departamentos.id = funcionarios.idDepartamentos
ORDER BY empresas.nome ASC;
I've tried to put WHERE in the end, right after ASC :
...ORDER BY empresas.nome ASC WHERE id.empresas = 2;
And none of my tries have worked.
Tables:
CREATE TABLE `departamentos` (
`id` int(11) NOT NULL,
`idEmpresas` int(11) DEFAULT NULL,
`nomeDepartamento` varchar(30) DEFAULT NULL
)
CREATE TABLE `empresas` (
`id` int(11) NOT NULL,
`nome` varchar(30) DEFAULT NULL
)
CREATE TABLE `funcionarios` (
`idFuncionarios` int(11) NOT NULL,
`idDepartamentos` int(11) DEFAULT NULL,
`nomeFuncionario` varchar(30) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`senha` varchar(30) DEFAULT NULL
)
What i wanna do is JOIN those table to return empresas.nome, departamentos.nomeDepartamento,
funcionarios.nomeFuncionario, funcionarios.email, funcionarios.idFuncionario and then select then by empresas.
Thank you for your help!
SELECT empresas.nome, departamentos.nomeDepartamento,
funcionarios.nomeFuncionario, funcionarios.email, funcionarios.idFuncionario FROM empresas
INNER JOIN departamentos ON empresas.id = departamentos.idEmpresas
INNER JOIN funcionarios ON departamentos.id = funcionarios.idDepartamentos
WHERE empreas.id = 2 /* <=== The line to add */
ORDER BY empresas.nome ASC;
I have 3 tables which I would like to "inner join" - but always to the first table!
SELECT *
FROM scene_block AS sb
INNER JOIN roles AS r ON (sb.selected_block = r.id
AND sb.block_type = 'role'
AND r.id NOT IN (21))
INNER JOIN script_actors AS sa ON (sb.selected_block = sa.id
AND sb.block_type = 'actor')
WHERE
sb.scene_id = '1'
GROUP BY
sb.id
ORDER BY
sb.position
The same query with LEFT JOIN returns all results as expected with the r.id 21 "NULL", the query with INNER JOIN returns 0 results (as there are all inner joins together)
Result Left Join
But that's not what I want to achieve...
I would like to achieve, that If on scene_block "block_type='role'" the roles table is gonna be inner joined, if block_type='actor' the script_actors is gonna be inner joined... and the link between the rows is alsways scene_block.selected_id = .id
Tables
CREATE TABLE `scene_block` (
`id` int(11) UNSIGNED NOT NULL,
`scene_id` int(11) NOT NULL,
`block_type` enum('actor','role') NOT NULL,
`selected_block` int(11) DEFAULT NULL,
`content` text NOT NULL,
`hideable` enum('0','1') NOT NULL DEFAULT '1',
`position` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `script_actors` (
`id` int(11) NOT NULL,
`script_id` int(11) NOT NULL,
`realname` varchar(200) NOT NULL,
`actorname` varchar(200) NOT NULL,
`description` text NOT NULL,
`position` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `roles` (
`id` int(11) UNSIGNED NOT NULL,
`location_id` int(11) NOT NULL,
`title` varchar(256) NOT NULL,
`color` varchar(7) NOT NULL,
`color_live` varchar(7) NOT NULL,
`position` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Without having tested it on your data I presume that you get closer to your desired result if you use INNER JOINs instead of LEFT JOINs.
SELECT *
FROM scene_block AS sb
INNER JOIN roles AS r ON (sb.selected_block = r.id
AND sb.block_type = 'role'
AND r.id NOT IN (21))
INNER JOIN script_actors AS sa ON (sb.selected_block = sa.id
AND sb.block_type = 'actor')
WHERE
sb.scene_id = '1'
GROUP BY
sb.id
ORDER BY
sb.position
Inner joins don't work here, because a scene block type cannot be 'role' and 'actor' at the same time. You need outer joins to get either the role or the actor. Then add a condition to get rid of scene blocks that have no match.
SELECT *
FROM scene_block AS sb
LEFT JOIN roles AS r ON sb.selected_block = r.id
AND sb.block_type = 'role'
AND r.id <> 21
LEFT JOIN script_actors AS sa ON sb.selected_block = sa.id
AND sb.block_type = 'actor'
WHERE sb.scene_id = 1
AND (sa.id IS NOT NULL OR r.id IS NOT NULL)
ORDER BY sb.position;
I Have closing balances in Akey table and i have pool id in cpp table i want to update value of Bppd key_amount column with akey closing_balance but before
that i have to check the default_pool='ACTIVE' from table cpp
sample tables are mentioned
TABLE Akey (
`id` int(11) NOT NULL,
`serial_key` varchar(82) DEFAULT NULL,
`closing_balance` double(20,2) DEFAULT '0.00',
`product_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
)
TABLE Bppd(
`id` int(11) NOT NULL AUTO_INCREMENT,
`pool_id` int(11) DEFAULT NULL,
`product_id` int(11) DEFAULT NULL,
`akey_id` int(11) DEFAULT NULL,
`key_amount` double DEFAULT '0',
`working_balance` double DEFAULT '0',
PRIMARY KEY (`id`)
)
TABLE Cpp (
`id` int(11) NOT NULL AUTO_INCREMENT,
`akey_id` int(11) DEFAULT NULL,
`pool_id` int(11) DEFAULT NULL,
`default_pool` varchar(15) DEFAULT NULL,
PRIMARY KEY (`id`)
)
I have Following query
UPDATE `Bppd` ppd
JOIN AKey kk ON ppd.`akey_id` = kk.`id`
JOIN `Cpp` pp ON pp.`akey_id` = kk.`id` AND pp.`default_pool` = 'ACTIVE' AND ppd.`akey_id` = pp.`akey_id`
SET ppd.`key_amount`= kk.`closing_balance`
Try this
UPDATE Bppd b INNER JOIN Akey a on a.id = b.akey_id AND a.product_id = b.product_id
INNER JOIN Cpp c ON b.key_id = c.akey_id AND b.pool_id = c.pool_id
SET b.key_amount = a.closing_balance
WHERE c.default_pool='ACTIVE'
Or this:
UPDATE Bppd b SET key_amount = (SELECT closing_balance FROM Akey a WHERE a.id = b.akey_id and a.product_id = b.product_id)
WHERE EXISTS (
SELECT 1 FROM Cpp c
WHERE b.akey_id = c.akey_id AND b.pool_id = c.pool_id
AND c.default_pool='ACTIVE'
)
AND EXISTS (
SELECT 1 FROM Akey a
WHERE a.id = b.akey_id and a.product_id = b.product_id
)
I have the following table structure in my code and I am trying to pull username and name fields from users table, but the query currently pulls only from_user_id data. How do I modify this so that I get two separate columns that lists username and name for both to_user_id and from_user_id?
SELECT f.id, from_user_id, to_user_id, STATUS, u.username, u.name
FROM friend f
left JOIN users u ON f.from_user_id = u.id
WHERE f.id IN(
SELECT source_id
FROM notification
WHERE user_id = 5 AND notification_read = 1)
users table:
CREATE TABLE `users` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(60) NOT NULL,
`password` VARCHAR(64) NOT NULL,
`enabled` TINYINT(4) NOT NULL DEFAULT '1',
`email` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`created_on` DATETIME NOT NULL,
`role` VARCHAR(50) NULL DEFAULT 'ROLE_USER',
PRIMARY KEY (`id`),
UNIQUE INDEX `username` (`username`)
)
and friend table:
CREATE TABLE `friend` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`from_user_id` BIGINT(20) NOT NULL,
`to_user_id` BIGINT(20) NOT NULL,
`status` INT(2) NOT NULL,
`requested_date` DATETIME NULL DEFAULT NULL,
`accepted_date` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `from_user_id` (`from_user_id`),
INDEX `to_user_id` (`to_user_id`)
)
and a notification table:
CREATE TABLE `notification` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`user_id` BIGINT(20) NOT NULL,
`activity_type` TINYINT(4) NOT NULL,
`source_id` BIGINT(20) NOT NULL,
`parent_id` BIGINT(20) NULL DEFAULT NULL,
`parent_type` TINYINT(4) NULL DEFAULT NULL,
`notification_read` TINYINT(4) NOT NULL DEFAULT '0',
`created_on` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `user_id` (`user_id`),
INDEX `created_on` (`created_on`)
)
You need to perform two joins against users - one for each side of the friend relationship, and include the appropriate columns in the SELECT list from both of those joins against users.
SELECT
f.id,
from_user_id,
to_user_id,
STATUS,
-- uf is an alias for the "from" user
-- You must alias the columns to distinguish them
uf.username AS from_username,
uf.name AS from_name,
-- ut is an alias for the "to" user
ut.username AS to_username,
ut.name AS to_name
FROM
friend f
-- Join first for the from user info
LEFT JOIN users uf ON f.from_user_id = uf.id
-- Join again for the to user info
LEFT JOIN users ut ON f.to_user_id = ut.id
WHERE f.id IN(
SELECT source_id
FROM notification
WHERE user_id = 5 AND notification_read = 1
)
A further note... You can substitute an INNER JOIN against notification instead of the IN () subquery, and you may achieve better performance.
SELECT
DISTINCT /* needed assuming multiple notification.source_id per f.id */
f.id,
from_user_id,
to_user_id,
STATUS,
uf.username AS from_username,
uf.name AS from_name,
ut.username AS to_username,
ut.name AS to_name
FROM
friend f
LEFT JOIN users uf ON f.from_user_id = uf.id
LEFT JOIN users ut ON f.to_user_id = ut.id
-- Join notification instead of the IN () subquery
INNER JOIN notification
ON f.id = notification.source_id
AND notification.user_id = 5
AND notification_read = 1
I've got the three tables below from which I wish to get the following selects:
1.) Select all items from collaboration and group them by group_id in group_members for a given user
This means that when the user logs in, (s)he will see all (and only) collaboration items belonging to the groups where he is group member.
2.) For each group_id, select all collaboration items.
This means that when a user selects any group (group_id) from 1 above, he's going to see all the collaborationitems belonging to the selected group (group_id)
Constraints: Each user MUST be a group member. The userstable is there to supply firstnameand lastname of user.
This is what I tried for 1 to no avail!
function OrderByGroup_id($username) {
$data = array();
$currenttime = time();
$q = "
SELECT *
FROM collaboration
INNER JOIN group_members ON collaboration.group_id = group_members.group_id
INNER JOIN users ON users.username = group_members.username
WHERE collaboration.parent_id IS NULL and collaboration.is_comment = 0
AND group_members.username = :user group by collaboration.group_id";
$sq = $this->connection->prepare($q);
$sq->execute(array(':user' => $username));
while($row = $sq->fetch()) {
$json = array();
$json['title'] = $row['title'];
$json['question'] = $row['content'];
$json['firstname'] = $row['firstname'];
$json['lastname'] = $row['lastname'];
$json['timestamp'] = $row['timestamp'];
$json['key'] = $row['group_id'];
$data[] = $json;
}
$allposts =json_encode($data);
return $allposts= json_decode($allposts, true);
}
Here are the tables
CREATE TABLE IF NOT EXISTS `collaboration` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`group_id` varchar(255) DEFAULT NULL,
`author` varchar(30) NOT NULL,
`title` varchar(255) DEFAULT NULL,
`content` text NOT NULL,
`is_comment` tinyint(1) unsigned NOT NULL,
`file` tinyint(1) unsigned NOT NULL DEFAULT '0',
`points` int(11) DEFAULT NULL,
`timestamp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`firstname` varchar(30) NOT NULL,
`lastname` varchar(30) NOT NULL,
`username` varchar(30) NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `group_members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`group_id` varchar(50) NOT NULL,
`status` tinyint(1) unsigned NOT NULL,
`timestamp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Thanks for your input!
The following select does deliver the request for question 1. However, I know the query is not optimal because I do select entries that I don't need at the moment. For example the use of *
I would like to select only title, content, timestamp, group_id, from collaboration and firstname, lastname, from users
SELECT * FROM collaboration
INNER JOIN group_members ON collaboration.group_id = group_members.group_id
INNER JOIN users ON users.username = collaboration.author
WHERE collaboration.parent_id IS NULL and collaboration.is_comment = 0
AND group_members.username = :user
GROUP BY collaboration.group_id
ORDER BY collaboration.timestamp DESC