Combining Multiple SELECT and CREATE queries in MySQL - mysql

In a PHP file I have multiple queries because I work with multiple tables, and with the data I get a and display such data. These queries could be merged into one? If anyone knows how I want to tell me what the code is like:
SELECT * FROM compras ;
SELECT * FROM clientes WHERE idcliente = '$row[idcliente]'
SELECT * FROM pedidos_ventas WHERE idcompra = '$row[idcompra]'
SELECT * FROM mercaderias WHERE idmerc = '$rowped[idmercaderia]' LIMIT 1
CREATE TABLE IF NOT EXISTS `clientes` (
`idcliente` INT(10) NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(50) NOT NULL,
`apellido` VARCHAR(50) NOT NULL,
`domicilio` VARCHAR(50) NOT NULL,
`telefono` VARCHAR(50) DEFAULT NULL,
`movil` VARCHAR(50) DEFAULT NULL,
`dni` VARCHAR(10) NOT NULL,
`familiar` VARCHAR(50) NOT NULL,
PRIMARY KEY (`idcliente`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `compras` (
`idcompra` INT(7) NOT NULL AUTO_INCREMENT,
`idcliente` INT(7) NOT NULL,
`observacion` text NOT NULL,
`fecha_ingreso` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`idcompra`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `entregas_ventas` (
`identrega` INT(11) NOT NULL AUTO_INCREMENT,
`idcompra` INT(11) NOT NULL,
`entrega` DOUBLE(7,2) NOT NULL,
`fecha` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`identrega`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `mercaderias` (
`idmerc` INT(7) NOT NULL AUTO_INCREMENT,
`cantidad` INT(5) NOT NULL,
`codigo` VARCHAR(20) NOT NULL,
`producto` VARCHAR(100) NOT NULL,
`preciofinal` DOUBLE(7,2) NOT NULL,
PRIMARY KEY (`idmerc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `pedidos_ventas` (
`idpedido` INT(7) NOT NULL AUTO_INCREMENT,
`idcompra` INT(7) NOT NULL,
`idmercaderia` INT(7) NOT NULL,
`kilo` DOUBLE(7,2) NOT NULL,
`precio` DOUBLE(7,2) NOT NULL,
PRIMARY KEY (`idpedido`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
select compras.idcompra, case when clientes.idcliente is null
then 'ninguno' else CONCAT(clientes.nombre, ',', clientes.apellido)
end as nombre, case when pedidos_ventas.idmercaderia = '-1' then 'Vianda saludable' when pedidos_ventas.idmercaderia = '-2' then 'Comida Sana' else mercaderias.producto end as mercaderia, pedidos_ventas.kilo, pedidos_ventas.precio from compras
left join clientes on (compras.idcliente=clientes.idcliente)
left join pedidos_ventas on (pedidos_ventas.idcompra=compras.idcompra)
left join mercaderias on (pedidos_ventas.idmercaderia=mercaderias.idmerc)
order by compras.idcompra asc
If now I would like to use the LIKE to see if it matches a value that I enter in an input $ _POST ['search'], either by customer name, vianda(lunch-box), food, or any merchandise ?? Try to do this and it does not work
SELECT compras.idcompra, CASE WHEN clientes.idcliente IS NULL
THEN 'ninguno' ELSE CONCAT(clientes.nombre, ',', clientes.apellido)
END AS nombre, CASE WHEN pedidos_ventas.idmercaderia = '-1' THEN 'Vianda saludable' WHEN pedidos_ventas.idmercaderia = '-2' THEN 'Comida Sana' ELSE mercaderias.producto END AS mercaderia, pedidos_ventas.kilo, pedidos_ventas.precio FROM compras
LEFT JOIN clientes ON (compras.idcliente=clientes.idcliente)
LEFT JOIN pedidos_ventas ON (pedidos_ventas.idcompra=compras.idcompra)
LEFT JOIN mercaderias ON (pedidos_ventas.idmercaderia=mercaderias.idmerc) WHERE mercaderias.producto LIKE '%comida%' OR..... LIKE clientes... or LIKE ..
ORDER BY compras.idcompra ASC

For a query with your current schema, try the following:
SELECT * FROM compras
INNER JOIN clientes ON (compras.idcliente = clientes.idcliente)
INNER JOIN pedidos_ventas ON (compras.id = pedidos_venta.id)
INNER JOIN mercaderias ON (pedidos_ventas.idmercaderia = mercaderias.idmerc)
WHERE clientes.idcliente = :clienteid
AND compras.idcompra = :compraid
AND mercaderias.idmerc = :mercaderiaid
IDEAL DATABASE DESIGN
Try adding foreign keys to your schema:
CREATE TABLE IF NOT EXISTS `cliente` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(50) NOT NULL,
`apellido` VARCHAR(50) NOT NULL,
`domicilio` VARCHAR(50) NOT NULL,
`telefono` VARCHAR(50) DEFAULT NULL,
`movil` VARCHAR(50) DEFAULT NULL,
`dni` VARCHAR(10) NOT NULL,
`familiar` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `mercaderia` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`cantidad` INT(5) NOT NULL,
`codigo` VARCHAR(20) NOT NULL,
`producto` VARCHAR(100) NOT NULL,
`preciofinal` DOUBLE(7,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `compra` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`cliente_id` INT(10) NOT NULL,
`observacion` text NOT NULL,
`fecha_ingreso` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
CONSTRAINT `fk_compra_cliente`
FOREIGN KEY (`cliente_id`)
REFERENCES `cliente` (`id`)
ON DELETE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `entregas_venta` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`compra_id` INT(10) NOT NULL,
`entrega` DOUBLE(7,2) NOT NULL,
`fecha` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
CONSTRAINT `fk_entregas_venta_compra`
FOREIGN KEY (`compra_id`)
REFERENCES `compra` (`id`)
ON DELETE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `pedidos_venta` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`compra_id` INT(10) NOT NULL,
`mercaderia_id` INT(10) NOT NULL,
`kilo` DOUBLE(7,2) NOT NULL,
`precio` DOUBLE(7,2) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_pedidos_venta_compra`
FOREIGN KEY (`compra_id`)
REFERENCES `compra` (`id`)
ON DELETE NO ACTION,
CONSTRAINT `fk_pedidos_venta_mercaderia`
FOREIGN KEY (`mercaderia_id`)
REFERENCES `mercaderia` (`id`)
ON DELETE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
And then use the query:
$stmt = $pdo->prepare(<<<SQL
SELECT * FROM compra
INNER JOIN cliente ON (compra.cliente_id = cliente.id)
INNER JOIN pedidos_venta ON (compra.id = pedidos_venta.id)
INNER JOIN mercaderia ON (pedidos_venta.mercaderia_id = mercaderia.id)
WHERE cliente.id = :clienteid
AND compra.id = :compraid
AND mercaderia.id = :mercaderiaid
SQL
);
$stmt->execute(':clienteid' => $clienteid, ':compraid' => $compraid, ':mercaderiaid' => $mercaderiaid);

Related

Get number products on stock

I have very difficult query and I need obtain parameters (parameterValue_id) and number products, which has such parameter, on stock. I would like count only that products which are comply with other criterias.
SELECT `parameters`.`parameter_from`, `parametervalues`.*, (SELECT IF (sumOfProductIN - sumOfProductOUT > 0, COUNT(productparametervalues.f_product_id), 0) FROM productparametervalues`
LEFT JOIN `products` ON products.product_id = productparametervalues.f_product_id
LEFT JOIN `categories` ON categories.category_id = products.f_category_id
LEFT JOIN (SELECT oi1.f_product_id, SUM(oi1.orderItem_numberUnits) AS sumOfProductIN
FROM orderitems oi1 WHERE oi1.orderItem_type = 'IN' GROUP BY oi1.f_product_id) AS `t` ON t.f_product_id = products.product_id
LEFT JOIN (SELECT oi2.f_product_id, SUM(oi2.orderItem_numberUnits) AS sumOfProductOUT
FROM orderitems oi2 WHERE oi2.orderItem_type = 'OUT' GROUP BY oi2.f_product_id) AS `t_2` ON t_2.f_product_id = products.product_id
LEFT JOIN `parametervalues` ON parametervalues.f_parameter_id = parameters.parameter_id
WHERE (category_lft >= '8') AND (category_rgt <= '19') AND (products.product_price >= '1') AND (products.product_price <= '2500') AND (products.product_enabled = 1)
WHERE (parameter_id = '4') AND (parameters.parameter_enabled = 1) AND (parametervalues.parameterValue_enabled = 1)
GROUP BY `parametervalues`.`parameterValue_id`) AS countProducts FROM `parameters`
Edit
table categories
CREATE TABLE IF NOT EXISTS `categories` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_title` varchar(255) DEFAULT NULL,
`category_description` text,
`f_parent_id` int(11) DEFAULT NULL,
`category_lft` smallint(6) DEFAULT NULL,
`category_rgt` smallint(6) DEFAULT NULL,
`category_depth` smallint(6) DEFAULT NULL,
`category_enabled` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
table orderitems
CREATE TABLE IF NOT EXISTS `orderitems` (
`orderItem_id` int(11) NOT NULL AUTO_INCREMENT,
`f_order_id` int(11) DEFAULT NULL,
`f_product_id` int(11) DEFAULT NULL,
`orderItem_title` varchar(50) DEFAULT NULL,
`orderItem_numberUnits` smallint(6) NOT NULL DEFAULT '1',
`orderItem_pricePerUnit` decimal(18,5) NOT NULL DEFAULT '0.00000',
`orderItem_price` float(18,5) NOT NULL DEFAULT '0.00000',
`orderItem_type` varchar(10) DEFAULT NULL,
PRIMARY KEY (`orderItem_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=95 ;
table parameters
CREATE TABLE IF NOT EXISTS `parameters` (
`parameter_id` int(11) NOT NULL AUTO_INCREMENT,
`f_parameterGroup_id` int(11) DEFAULT NULL,
`parameter_title` varchar(100) DEFAULT NULL,
`parameter_enabled` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`parameter_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
table parametervalues
CREATE TABLE IF NOT EXISTS `parametervalues` (
`parameterValue_id` int(11) NOT NULL AUTO_INCREMENT,
`f_parameter_id` int(11) NOT NULL,
`parameterValue_title` varchar(100) NOT NULL,
`parameterValue_enabled` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`parameterValue_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;
table productparametervalues
CREATE TABLE IF NOT EXISTS `productparametervalues` (
`f_product_id` int(11) NOT NULL AUTO_INCREMENT,
`f_parameter_id` int(11) NOT NULL DEFAULT '0',
`f_parameterValue_id` int(11) NOT NULL DEFAULT '0',
`productParameter_value` varchar(100) DEFAULT NULL,
PRIMARY KEY (`f_product_id`,`f_parameter_id`,`f_parameterValue_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;
table products
CREATE TABLE IF NOT EXISTS `products` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`f_category_id` int(11) DEFAULT NULL,
`f_brand_id` int(11) DEFAULT NULL,
`product_title` varchar(100) DEFAULT NULL,
`product_description` text,
`product_price` float(10,2) DEFAULT NULL,
`product_enabled` tinyint(1) DEFAULT '0',
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=43 ;

MySQL returns only one result

This is my product table:
CREATE TABLE `products` (
`idproduct` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`description` text NOT NULL,
`price` double unsigned NOT NULL,
`shipping` double unsigned DEFAULT NULL,
`condition` int(10) unsigned NOT NULL,
`returns` int(10) unsigned NOT NULL,
`date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`image` varchar(255) DEFAULT NULL,
PRIMARY KEY (`idproduct`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8
And this is my product_categories table
CREATE TABLE `products_subcategories` (
`idproduct_category` int(10) unsigned NOT NULL AUTO_INCREMENT,
`idproduct` int(10) unsigned NOT NULL,
`idsubcategory` int(10) unsigned NOT NULL,
PRIMARY KEY (`idproduct_category`),
KEY `products_categories_products_idx` (`idproduct`),
KEY `products_categories_categories_idx` (`idsubcategory`),
CONSTRAINT `products_subcategories_products` FOREIGN KEY (`idproduct`) REFERENCES `products` (`idproduct`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `products_subcategories_subcategories` FOREIGN KEY (`idsubcategory`) REFERENCES `subcategories` (`idSubcategory`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
I trying to search in products like that:
Select products.* from products
INNER JOIN products_subcategories
ON products.idproduct = products_subcategories.idproduct
WHERE name LIKE '%p%'
but it returns only one row.. without inner join it returns me more rows

Fail to create relationship between two tables

I have two tables :
CREATE TABLE `Users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) NOT NULL DEFAULT '',
`last_name` varchar(50) NOT NULL DEFAULT '',
`login` varchar(50) NOT NULL DEFAULT '',
`password` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
AND
CREATE TABLE `Books` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL DEFAULT '',
`author` varchar(50) NOT NULL DEFAULT '',
`year` int(4) NOT NULL,
`available` int(3) NOT NULL DEFAULT '0',
`availabledate` date NOT NULL,
`user_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
I am trying to create a relationship between those two, so that one user may have multiple books (user_id) but whatever I'm doing I'm getting errors. Either
Cannot add or update a child row: a foreign key constraint fails
(bookstore.,
CONSTRAINT books_fk FOREIGN KEY (user_id) REFERENCES users
(user_id) ON DELETE CASCADE ON UPDATE CASCADE)
or before I didn't use unsigned int in the Books table and I said that default value is 0 (which I would prefere but I don't think I can do that?) In that case I got error 150.
I'd recommend, to change your database schema. Why?
Can a book exist without having a user? If yes, you shouldn't have a foreign key from books referencing users. Can a user exist without having a book? If yes, you shouldn't have a foreign key from users referencing books.
Can a user have multiple books? And a book multiple users? If yes, you have a m:n relationship. This means you need a bridge table.
In your tables you don't need foreign keys:
CREATE TABLE `Users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) NOT NULL DEFAULT '',
`last_name` varchar(50) NOT NULL DEFAULT '',
`login` varchar(50) NOT NULL DEFAULT '',
`password` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
CREATE TABLE `Books` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL DEFAULT '',
`author` varchar(50) NOT NULL DEFAULT '',
`year` int(4) NOT NULL,
`available` int(3) NOT NULL DEFAULT '0',
`availabledate` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
And a bridge table would look like this:
CREATE TABLE books_users (
book_id int(11) unsigned NOT NULL,
user_id int(11) unsigned NOT NULL,
PRIMARY KEY (book_id, user_id),
KEY idx_user_id (user_id),
FOREIGN KEY fk_books (book_id) REFERENCES Books(id),
FOREIGN KEY fk_users (user_id) REFERENCES Users(user_id)
) ENGINE=InnoDB;
This solves both problems and is common practice.
To query both users and books in one query, you join them like this:
SELECT
whatever
FROM
Books b
INNER JOIN books_users bu ON b.id = bu.book_id
INNER JOIN users u ON bu.user_id = u.user_id
WHERE user_id = 1 /*for example*/
;
If you want to insert something in the tables, just do the insert and get the id which was generated for the row with SELECT LAST_INSERT_ID();, then insert this id in the books_users bridge table.
Updates don't affect anything, you can simply perform them on users or books. If you really really have to update the auto_increment column (which usually isn't needed and not recommended) you can add ON UPDATE CASCADE after the foreign keys in the books_users table.
Change these lines and try again
change user_id int(11) unsigned NOT NULL AUTO_INCREMENT to user_id
int(11) NOT NULL AUTO_INCREMENT
and
id int(11) unsigned NOT NULL AUTO_INCREMENT, to id int(11) NOT
NULL AUTO_INCREMENT,
and
user_id int(11) unsigned NOT NULL, to user_id int(11) NOT NULL,
Finally try
CREATE TABLE `Users` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) NOT NULL DEFAULT '',
`last_name` varchar(50) NOT NULL DEFAULT '',
`login` varchar(50) NOT NULL DEFAULT '',
`password` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
and
CREATE TABLE `Books` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL DEFAULT '',
`author` varchar(50) NOT NULL DEFAULT '',
`year` int(4) NOT NULL,
`available` int(3) NOT NULL DEFAULT '0',
`availabledate` date NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
If you are using Mysql then you must use InnoDB database engine to enable relationship between two tables
MyISAM will not allow this relationship
alter table `users` add constraint `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
or you can use this query for cascade edit delete
alter table `users` add constraint `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
This is your new DDL for two tables try this
CREATE TABLE IF NOT EXISTS `books` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL DEFAULT '',
`author` varchar(50) NOT NULL DEFAULT '',
`year` int(4) NOT NULL,
`available` int(3) NOT NULL DEFAULT '0',
`availabledate` date NOT NULL,
`user_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) NOT NULL DEFAULT '',
`last_name` varchar(50) NOT NULL DEFAULT '',
`login` varchar(50) NOT NULL DEFAULT '',
`password` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `users`
--
ALTER TABLE `users`
ADD CONSTRAINT `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

3 tables or 1 table?

CREATE TABLE IF NOT EXISTS `domains` (
`domains_id` bigint(15) NOT NULL AUTO_INCREMENT,
`domains_url` varchar(255) NOT NULL,
PRIMARY KEY (`domains_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `domains_actions` (
`domains_actions_id` int(15) NOT NULL AUTO_INCREMENT,
`domains_actions_selmgec` int(15) NOT NULL,
`domains_id` int(15) NOT NULL,
`domains_actions_member` int(15) NOT NULL,
`domains_actions_date` date NOT NULL,
`actions_id` int(2) NOT NULL
`domains_actions_value` int(15) NOT NULL,
PRIMARY KEY (`domains_actions_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `actions` (
`actions_id` int(15) NOT NULL AUTO_INCREMENT,
`actions_action` varchar(15) NOT NULL,
PRIMARY KEY (`actions_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
So if I have read properly, I need an actions tables for the likes/new/social then this is linked into domains_actions.
Not sure what you're trying to do with these, but they obviously have repeating data. You should consolidate into one table with a type column; perhaps using ENUM.
CREATE TABLE IF NOT EXISTS `domains` (
`domains_id` int(15) NOT NULL AUTO_INCREMENT,
`domains_selmgec` int(15) NOT NULL,
`domains_domain` int(15) NOT NULL,
`domains_member` int(15) NOT NULL,
`domains_date` date NOT NULL,
`domains_type` int(2) NOT NULL,
`type` ENUM('likes', 'new', 'social'),
PRIMARY KEY (`domains_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
A more relational and normalized schema would look something like:
CREATE TABLE IF NOT EXISTS `domain` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`selmgec` int(15) NOT NULL,
`domain` int(15) NOT NULL,
`member` int(15) NOT NULL,
`date` date NOT NULL,
`type` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `type` (
`id` tinyint(1) NOT NULL AUTO_INCREMENT,
`type` varchar(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `domainType` (
`domain_id` int(15) NOT NULL,
`type_id` tinyint(1) NOT NULL,
PRIMARY KEY (`domain_id`, `type_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
This design will allow you hold a single domain and assign it multiple types. You would need to change the engine to InnoDb and create foreign key constrains to enforce these types.
See the demo
Without knowing all of the details, I would create one table and then a TypeId column that references another table:
CREATE TABLE IF NOT EXISTS `domains` (
`domains_id` int(15) NOT NULL AUTO_INCREMENT,
`domains_selmgec` int(15) NOT NULL,
`domains_domain` int(15) NOT NULL,
`domains_member` int(15) NOT NULL,
`domains_date` date NOT NULL,
`domains_type` int(2) NOT NULL,
`type_id` int(2) NOT NULL,
PRIMARY KEY (`domains_likes_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `types` (
`type_id` int(15) NOT NULL AUTO_INCREMENT,
`type_name` varchar(15) NOT NULL,
PRIMARY KEY (`type_id`)
) ;

SQL query; inner join on 4 tables

Is this the most efficient way of joining these 4 tables? Also is it possible to only have some rows of each tables selected? I tried changing * to a name of a column but only the columns from studentlist are allowed.
SELECT c.classID, c.instrument, c.grade, u.ID, u.firstname, u.lastname, u.lastsongplayed, u.title
FROM studentlist s
INNER JOIN classlist c ON s.listID = c.classID
INNER JOIN (
SELECT *
FROM users u
INNER JOIN library l ON u.lastsongplayed = l.fileID
)
u ON s.studentID = u.ID
WHERE teacherID =3
ORDER BY classID
LIMIT 0 , 30
Database structure:
CREATE TABLE IF NOT EXISTS `classlist` (
`classID` int(11) NOT NULL AUTO_INCREMENT,
`teacherID` int(11) NOT NULL,
`instrument` text,
`grade` int(11) DEFAULT NULL,
PRIMARY KEY (`classID`),
KEY `teacherID_2` (`teacherID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
CREATE TABLE IF NOT EXISTS `studentlist` (
`listID` int(11) NOT NULL,
`studentID` int(11) NOT NULL,
KEY `teacherID` (`studentID`),
KEY `studentID` (`studentID`),
KEY `listID` (`listID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(60) NOT NULL,
`password` varchar(60) NOT NULL,
`firstname` text NOT NULL,
`lastname` text NOT NULL,
`sessionID` varchar(60) DEFAULT NULL,
`lastlogin` time DEFAULT NULL,
`registerdate` date NOT NULL,
`isteacher` tinyint(1) DEFAULT NULL,
`isstudent` tinyint(1) DEFAULT NULL,
`iscomposer` tinyint(1) DEFAULT NULL,
`lastsongplayed` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`),
UNIQUE KEY `email` (`email`,`sessionID`),
KEY `ID_2` (`ID`),
KEY `ID_3` (`ID`),
KEY `lastsongplayed` (`lastsongplayed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=63 ;
CREATE TABLE IF NOT EXISTS `library` (
`fileID` int(11) NOT NULL AUTO_INCREMENT,
`userID` int(11) NOT NULL,
`uploaddate` datetime NOT NULL,
`title` varchar(60) NOT NULL,
`OrigComposer` varchar(60) NOT NULL,
`composer` varchar(60) NOT NULL,
`genre` varchar(60) DEFAULT NULL,
`year` year(4) DEFAULT NULL,
`arrangement` varchar(60) DEFAULT NULL,
PRIMARY KEY (`fileID`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=77 ;
Is this the most efficient way of joining these 3 tables?
Your JOIN looks correct and you are joining on your keys. So this should be efficient. However, I would encourage you to analyze your query with EXPLAIN to determine additional optimizations.
Is it possible to only have some rows of each tables selected?
Yes. Change * to be the columns from each table you want. I encourage you to explicitly prefix them with the originating table. Depending on the columns you select, this could also make your query more performant.
SELECT studentlist.studentID, users.email FROM ...