Reputation: 1405
I'm doing a products system where a product can be included inside a collection.
In products' page I show all the products, BUT if some product is INSIDE a collection, I need to display only the collection name and NOT the product itself. I mean, hide the products who are inside a collection and show the collection once while also showing the others products (without collection).
TABLE 1: colecciones ("collections" in Spanish) - Where I store the ID and name of the collection.
CREATE TABLE `colecciones` (
`id` INT(255) NOT NULL AUTO_INCREMENT ,
`nombre` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`id`)
);
INSERT INTO `colecciones`
(`nombre`)
VALUES
('dulce'),('salado'),('agrio')
;
http://sqlfiddle.com/#!9/8534e/1/0
TABLE 2: productos ("products") - Where I store the products and, if it is inside a collection, the collection ID (column "coleccion"). If not, the value is 0.
CREATE TABLE `productos` (
`id` INT(255) NOT NULL AUTO_INCREMENT ,
`nombre` VARCHAR(100) NOT NULL ,
`coleccion` INT(255) NOT NULL ,
PRIMARY KEY (`id`)
);
INSERT INTO `productos`
(`nombre`, `coleccion`)
VALUES
('manzana',1),('salmon',2),('sandia',0),('sopa',3),('pera',1),('agua',0)
;
http://sqlfiddle.com/#!9/6aef2/1/0
Looking at the example, the product with name "manzana" (apple) is part of collection "dulce" (sweet), and the product "agua" (water) isn't part of any collection.
What I expect to show is this:
<h1>My products</h1>
dulce /* (ID 1 table `colecciones`) because I have products with "coleccion = 1" */
salado /* (ID 2 table `colecciones`) because I have products with "coleccion = 2" */
sandia /* the product itself, not collection */
agrio /* (ID 3 table `colecciones`) because I have products with "coleccion = 3" */
agua /* the product itself, not collection */
I'm stuck with this. How can I display the data in this way with PHP?
I need to order like productos.id DESC
, which I accomplished by adding at the end:
ORDER BY c.`id` DESC
Upvotes: 0
Views: 83
Reputation: 1269883
I think an aggregation will do what you want:
select (case when c.name is not null then c.name else p.name end) as name
from productos p left join
colecciones c
on p.coleccion = c.id
group by name, (c.name is not null);
The second condition in the group by
just ensures that you get two rows when the product and coleccion have the same name.
I also think this will work for your purposes:
select p.name from productos where coleccion = 0
union all
select c.name from colecciones;
You seem to want all products not in a collection plus the collection names (which is what this query does).
EDIT:
I'm not sure which id you want, but you could do:
select p.name, p.id from productos where coleccion = 0
union all
select c.name, c.id from colecciones
order by id desc;
Upvotes: 1
Reputation: 18964
If the order doesn't matter, just use two queries:
SELECT * FROM productos WHERE coleccion = 0;
This will give you all the products that are not in a collection. Although, I would suggest using NULL
instead of 0
.
Second query:
SELECT colecciones.* FROM productos
INNER JOIN colecciones on colecciones.id = productos.coleccion
GROUP BY coleccion;
This will give you all of the collections that have products.
Upvotes: 1