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;
Related
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;
How can I return, on a select, a field that indicates that an id was found?
My goal is to return all songs(song) from a specific source(source) checking if an user(user) has it or not (user_song).
The query I made almost works. If I remove 'hasSong' (which Im trying to indicate that an user has a song or not), I can see all songs.
If I keep 'hasSong', I see all songs repeating the song for each user.
QUERY:
SELECT DISTINCT(song.id) AS id_song, CONCAT(song.article, ' ', song.name) AS name
FROM `song`
LEFT JOIN `user_song` ON `song`.`id` = `user_song`.`id_song`
LEFT JOIN `user` ON `user`.`id` = `user_song`.`id_user`
JOIN `song_source` ON `song`.`id` = `song_source`.`id_song`
WHERE `song_source`.`id_source` = '1'
AND ( `user_song`.`id_user` = '3' OR song.id = song_source.id_song )
ORDER BY `song`.`name` ASC
DB:
CREATE TABLE `song` (
`id` int(11) NOT NULL,
`article` varchar(10) NOT NULL,
`name` varchar(150) NOT NULL,
`shortname` varchar(150) NOT NULL,
`year` int(11) NOT NULL,
`artist` int(11) NOT NULL,
`duration` int(11) NOT NULL,
`genre` int(11) NOT NULL,
`updated` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `song_source` (
`id_song` int(11) NOT NULL,
`id_source` int(11) NOT NULL
)
CREATE TABLE `source` (
`id` int(11) NOT NULL,
`article` varchar(10) NOT NULL,
`name` varchar(150) NOT NULL,
`updated` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_song` (
`id_user` int(11) NOT NULL,
`id_song` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The specification isn't entirely clear, ...
To return all songs (with no repeated values of song.id) that are from a particular source (id_source='1'),
along with an indicator, a value of 0 or 1, that tells us if there's a row in user_song that matches on id_song and is related to a particular user,(id_user = '3')
something like this:
SELECT s.id AS id_song
, MAX( CONCAT(s.article,' ',s.name) ) AS name
, MAX( IF(us.id_user = '3' ,1,0) ) AS has_song
FROM `song` s
JOIN `song_source` ss
ON ss.id_song = s.id
AND ss.id_source = '1'
LEFT
JOIN `user_song` us
ON us.id_song = s.id
AND us.id_user = '3'
GROUP BY s.id
ORDER BY MAX(s.name)
There are a couple of other query patterns that will return an equivalent result. For example, we could use a correlated subquery in the SELECT list.
SELECT s.id AS id_song
, MAX( CONCAT(s.article,' ',s.name) ) AS name
, ( SELECT IF( COUNT(us.id_user) >0,1,0)
FROM `user_song` us
WHERE us.id_song = s.id
AND us.id_user = '3'
) AS has_song
FROM `song` s
JOIN `song_source` ss
ON ss.id_song = s.id
AND ss.id_source = '1'
GROUP BY s.id
ORDER BY MAX(s.name)
These queries are complicated by the fact that there are no guarantees of uniqueness in any of the tables. If we had guarantees, we could eliminate the need for a GROUP BY and aggregate functions.
Please consider adding PRIMARY and/or UNIQUE KEY constraints on the tables, to prevent duplication. The way the tables are defined, we could add multiple rows to song with the same id value. (And those could have different name values.)
(And the queries would be much simpler if we had some guarantees of uniqueness.)
I am trying to check if the user owns a course, I am trying to do this by getting the transaction_id (someone who's applied to a course) and then left join the courses and check the course_user against a session where the transaction_course is equal to course id
My SQL
UPDATE training_transactions
LEFT JOIN training
ON training_transactions.training_transaction_id =
training.course_id
SET training_transactions.training_transaction_status = 'declined'
WHERE training_transactions.training_transaction_id = ?
AND training.course_user = ?
training_transaction:
CREATE TABLE IF NOT EXISTS `training_transactions` (
`training_transaction_id` int(11) NOT NULL,
`training_transaction_user` int(11) NOT NULL,
`training_transaction_course` int(11) NOT NULL,
`training_transaction_status` varchar(50) NOT NULL,
`training_transaction_enabled` varchar(50) NOT NULL DEFAULT 'enabled',
`training_transaction_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
training
CREATE TABLE IF NOT EXISTS `training` (
`course_id` int(11) NOT NULL,
`course_user` int(11) NOT NULL,
`course_type` varchar(255) NOT NULL,
`course_name` varchar(255) NOT NULL,
`course_location` varchar(255) NOT NULL,
`course_duration` varchar(255) NOT NULL,
`course_fitness_type` varchar(255) NOT NULL,
`course_instructor_name` varchar(255) NOT NULL,
`course_price` int(15) NOT NULL,
`course_start_date` date NOT NULL,
`course_max_attendees` int(8) NOT NULL,
`course_accommodation` varchar(255) NOT NULL,
`course_accommodation_price` varchar(255) NOT NULL,
`course_status` varchar(50) NOT NULL,
`course_enabled` varchar(10) NOT NULL DEFAULT 'enabled'
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=latin1;
So my question, how can I update if the transaction id matches the course_id and the user's session (below) matches the course_user?
Session::get('id') // user id
You should be testing training_transaction_course in the WHEN clause, not training_transaction_id. And you should use INNER JOIN, not LEFT JOIN; you only need LEFT JOIN if you need to get rows in the first table that have no matches in the second table.
UPDATE training_transactions AS tt
INNER JOIN training AS t ON tt.training_transaction_id = t.course_id
SET tt.training_transaction_status = 'declined'
WHERE tt.training_transaction_course = ?
AND t.course_user = ?
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