mysql return same rows union - php

In my database i have categories, offers and coupons. i would like to count offers and coupons that exist in each category. when i use union it returns the same category twice.
i have the below query that returning same category rows with same name. i try to use union distinct but it does not work.
(SELECT
cat1.id AS cat1id, cat1.title AS title,
count(offers.id) AS offercounter
FROM cat1
INNER JOIN offers
ON offers.category=cat1.title
GROUP BY cat1.id
order by cat1.order)
UNION
(SELECT
cat1.id AS cat1id, cat1.title AS title,
count(coupons.id) AS couponscounter
FROM cat1
INNER JOIN coupons
ON coupons.category=cat1.title
GROUP BY cat1.id
order by cat1.order)
the result
cat1id title offercounter
2 Food 5388
23 Clothes 6000(this is offers)
32 Technology 499
40 Clothes 4(this is coupons)
i would like clothes to be (offercounter + couponscounter).
example: clothes=6004 and not two different rows
the desired result would be :
cat1id title offercounter
2 Food 5388
23 Clothes 6004(offers+coupons)
32 Technology 499

Alternative avoiding unions or sub queries is to use a couple of LEFT OUTER JOINS, and count the distinct ids from each table:-
SELECT cat1.id AS cat1id,
cat1.title AS title,
COUNT(DISTINCT offers.id) + COUNT(DISTINCT coupons.id) AS offercounter
FROM cat1
LEFT OUTER JOIN offers ON offers.category = cat1.title
LEFT OUTER JOIN coupons ON coupons.category = cat1.title
GROUP BY cat1.id AS cat1id,
cat1.title AS title
EDIT
A left outer join will return a row of nulls when there is no matching row.
For example if there was a row on cat1 with a matching row on offers but no matching row on coupons then the resulting row would consist of the row from cat1, the row from offers and the fields from coupons would be null.
This SQL will get every combination of matching rows. So if you had:-
cat1 fields offers fields coupons fields
id title id category id category
1 fred 99 fred 77 fred
1 fred 99 fred 88 fred
1 fred 100 fred 77 fred
1 fred 100 fred 88 fred
2 burt 120 fred NULL NULL
2 burt 121 fred NULL NULL
Hence the count uses DISTINCT to only could each id within a category once. As COUNT(field name) only counts non null values, with this example data for the 2nd category the count from coupons will be 0.

Union returns distinct rows. Your returned rows are distinct indeed. What you need to do to get your desired result is aggregate after unioning.
select min(cat1id) as cat1id, title, sum(offercounter) as offercounter
from
(your_query) as subquery
group by title
replace your_query with your existing query

Why don't you simple sum up the offercounter and use group by with order by cat1id.
SELECT cat1id,title,sum(offercounter) as offercounter
FROM offers GROUP BY title ORDER BY cat1id
View : SQL Fiddle
Output :
cat1id title offercounter
2 Food 5388
23 Clothes 6004
32 Technology 499

May be this can help.
SELECT cat1.id AS cat1id, cat1.title AS title ,((SELECT COUNT(offers.id) FROM offers WHERE offers.category=cat1.title)+(SELECT COUNT(coupons.id) FROM coupons WHERE coupons.category=cat1.title)) AS offercounter
FROM cat1

Related

Projecting mySQL database, how to deal with multiple categories

I need a help with projecting my database. The purpose of this database will be to show offers in different categories. There are 1-6 categories to each item. There are around 80 categories types, so I decided to make three tables as below:
table1:
ID Item_id
1 1
2 2
3 3
4 4
5 5
table2:
ID Item_id Category
1 1 cat55
2 1 cat56
3 1 cat57
4 1 cat58
5 2 cat42
6 2 cat43
7 2 cat44
8 2 cat45
9 3 cat42
etc.
table3:
Category_id category_name
cat55 apples
cat56 oranges
cat57 bananas
cat58 pineapples
Am I doing this right? I've got a problem to make proper sql query to show my categories in php, because when I use this query:
SELECT table1.*, table2.*, table3.*
FROM table1
INNER JOIN table2
ON table1.item_id = table2.item_id
INNER JOIN table3
ON table2.category=table3.category_id
It only gives me the first category name, when I need all of them and show them like this:
Item 1: apples, oranges, bananas, pineapples
Item 2: cat42, cat43, cat44, cat45
Item 3: cat42
What am I doing wrong? Is it wrong query or I need to change the database structure to like this
table 1 and 3 unchanged
table 2:
ID Item_id c1 c2 c3 c4 c5 c6
1 1 cat55 cat56 cat57 cat58 null null
2 2 cat42 cat43 cat44 cat45 null null
3 3 cat42 null null null null null
I'm using foreach loop, so I can do only one query, I know that more queries are possible, but I need to make it as simple as possible.
If you want to fetch all names in single row for each item, following query will work:
SELECT table1.Item_Id,Group_Concat(t3.category_name separator ',') as Category_Name
FROM table1
INNER JOIN table2
ON table1.item_id = table2.item_id
INNER JOIN table3
ON table2.category=table3.category_id
Group by table1.Item_Id;
I don't find any problem in your DB Structure.
Hope it helps!

Min() with INNER JOIN and Full-text-search

So Ive got the following Query to work just fine, searching for 'test*' in 'products_desc' column and fetching all its prices in the 'prices' table.
SELECT products.id, prices.price, products.product_desc FROM products
INNER JOIN prices
ON prices.product_id = products.id
WHERE
MATCH (products.product_desc) AGAINST ('test*' IN BOOLEAN MODE)
Although the 'prices' table consists of multiple prices per product and I only want to fetch the lowest one to each product. I've previously filtered the prices using
INNER JOIN (
SELECT min(price) as price, prices.product_number as product_number FROM prices
WHERE prices.product_number LIKE'".$q."%'
GROUP BY prices.product_number
) min_prices
on prices.price = min_prices.price
and prices.product_number = min_prices.product_number
but this was when I used products_numbers within the prices table (now there is just a product_id-column.
Products
id | product_desc
----------------------------------------
1 | product1
2 | product2
Prices
id | product_id | price
------------------------------------------------
1 | 1 | 312
2 | 1 | 219
3 | 2 | 312
4 | 2 | 111
Also, the table consists of 10+ million rows so, efficiency matters a lot :)
EDIT
What if I need to access value of columns on the min(prices.price) row?
SELECT products.id, MIN(prices.price) as prices_price, prices.id as prices_id, products.product_desc, products.product_number, prices.supplier_id, suppliers.name FROM products
INNER JOIN prices
ON prices.product_id = products.id
INNER JOIN suppliers
ON prices.supplier_id = suppliers.id
WHERE
MATCH (products.product_desc) AGAINST ('test*' IN BOOLEAN MODE)
GROUP BY prices.product_id
The above returns the lowest price per product but also the wrong value in the other columns?
You can use GROUP BY for this, with MIN() group by function.
GROUP BY is used to group values from a column, and perform calculations on column.
In our case we want to group the result by product_id as it's repeating in second table and perform calculation (min()) on price column of second table.
This is how your Query would look like:
SELECT products.id, MIN(prices.price), products.product_desc FROM products
INNER JOIN prices
ON prices.product_id = products.id
WHERE
MATCH (products.product_desc) AGAINST ('test*' IN BOOLEAN MODE)
GROUP BY prices.product_id

Count across multiple columns

I want to find in Dx1, Dx2, Dx3 add the number of times the same category and group repeats the name of the category.
Table Categories:
ID Name
1 A
2 B
Table Dx:
ID Dx 1 Dx 2 Dx 3
1 1 1 1
2 1 1 2
Result query:
Category_name Count_dx*
A 5
B 1
Thanks.
I am giving the answer although your question seems implicit.
SELECT
Categories.Name,
COUNT(*) AS Count_dx
FROM Categories
INNER JOIN
(
SELECT
Dx1 dx_val
FROM Dx
UNION ALL
SELECT
Dx2 dx_val
FROM Dx
UNION ALL
SELECT
Dx3 dx_val
FROM Dx
) AS t
ON Categories.ID = t.dx_val
GROUP BY t.dx_val;
Probably you want to get the count of category IDs (for each category) across the three columns (Dx1, Dx2 and Dx3) in Dx table. If so then the above query does the job.

how to loop through multiple categories in sigle row using php and mysql

i have a database name category
parent_cat cat_id title
0 1 fruit
0 2 vehicle
0 3 goods
1 4 sour
1 5 sweet
1 6 mixed
2 7 sedan
2 8 hatchback
2 9 car
and i store a object in database table name product
obj_name parent_cat sub_id
mango 1 4,5,
maruti 2 7,8,9
bmw 2 7,9
i want to join the two table to show the data so i need to pass the parameter in URL ie. ?obj=vehicle i got by doing sql query
SELECT category.cat_id,category.title,product.parent_cat,product.obj_name
FROM category, product
WHERE category.cat_id=product.parent_cat
AND category.title='$title' --is a difined get variable
if title=fruit i got "mango" if title=vehicle i got maruti and bmw
i want to know if title=sedan or title=car then how can i get maruti and bmw
through loop any solution
You might want to use a LEFT JOIN query, if you have comma separated values for title use IN()
SELECT a.cat_id, a.title, b.parent_cat, b.obj_name
FROM product b
LEFT JOIN category a
ON a.cat_id = b.parent_cat
WHERE a.title IN($title);
Try this:
SELECT category.cat_id, category.title, product.obj_name, product.parent_cat, product.sub_id FROM category
LEFT JOIN product ON category.cat_id = product.parent_cat OR category.cat_id LIKE '%product.sub_id%'
WHERE category.title LIKE '%$title%'
Use LIKE instead of = when you're not sure of the exact data you're comparing or looking for.
[UPDATE]
SELECT category.cat_id, category.title, product.obj_name, product.parent_cat, product.sub_id FROM product
LEFT JOIN category ON (product.parent_cat = category.cat_id OR product.sub_id LIKE '%category.cat_id%') AND category.title LIKE '%$title%'
I'm joining the table in wrong direction, sorry for that.

How can i use sql count in these multiple tables?

I am still a php/mysql newbie and I am working on mysql table relationship concept and i am having an issue with using mysql count in multiple table. Here is my db structure.
**product table**
id product_name product_img groupeid
1 Sneaker Mark sneaker_adi.png 1
2 bag Eric bageric.png 2
3 Sneaker Etoi sneakeretoi.jpg 1
**groupe table**
group_id group_name
1 men
2 women
**category table**
catid catname
1 sneaker-shoes
2 bag-woman
**productcategory table**
prod_id cat_ID
1 1
2 2
3 1
What i want to do is to determine the number of sneaker-shoes using mysql.
We can see that the number of sneaker-shoes in the db is 2.
But how can i use **count()** in these multiple tables.
I tried like this;
$sql = "SELECT COUNT(*) product.id,product_name,catname FROM product INNER JOIN productcategory ON product.id = prod_id INNER JOIN category ON catid = cat_ID WHERE catname='sneaker-shoes'";
i got error like:
Fatal error: Call to a member function execute() on a non-object in C:\wamp\www\kbashopping\Homme\index.php on line 32
Hope i exposed the issue clearly, any help and assistance will be appreciate
Thanks
If you are looking only for the count, mention only the count phrase in the Select clause.
Change :
SELECT COUNT(*) product.id,product_name,catname FROM
to :
SELECT COUNT(product.id) FROM
SELECT count (pc.cat_ID) FROM productcategory pc inner join category c on c.catid = pc.cat_ID where c.catname = 'sneaker shoes';
This will build a temporary table in mysql that joins category and product category but only including results where the catname is sneaker shoes. Then it selects a column to run the count operation on, and returns the result of count.

Categories