mysql join show replicate result - php

hello stackoverflow community :) ,
I have a complex join query is causing me lots of troubles :/
i have 3 tables here.
1: table [taxonomys t]
id ownerId type
1 1 office
2 1 inventory
3 1 inventory_item
2: table [tax_links l]
id parent son
1 1 2
2 1 3
3: table [settings s]
id taxId title value type
1 1 name office1 taxonomy
2 1 location Address taxonomy
3 1 settings on tax_links
so
1. taxonomy table containes all resourses of a user
2. link_taxs link 2 taxonomys to each others
3. settings save settings for resource , in case i want settings to be related to relations (not global) i set type in settings to tax_links
My query should return all resources of user, and concentrate all related as sons, and the id of relations in relsId.
SELECT `t`.`id`, group_concat(l.son) as sons, group_concat(l.id) as relsId, group_concat( s.title ) as titles, group_concat( s.value ) as vals, `t`.`name`, `t`.`type`, group_concat(s.id) as sid
FROM (`taxonomys` t)
LEFT JOIN `tax_links` l ON `l`.`parent` = `t`.`id`
LEFT JOIN `settings` s ON `s`.`taxId` = `t`.`id` and s.table = 'taxonomy'
WHERE `t`.`ownerId` = 1
GROUP BY `t`.`id`
it runs perfect, and return all what i need EXCEPT THAT it return REPLICATED results in sons,relsId.
for example tables i provided when i run this query i expect the result to be
id sons relsId titles vals
1 2,3 1,2 name,location office1,address
problem is when i run my query it return duplicate content for sons and relsId so i get something like
id sons relsId titles vals
1 2,3,2,3 1,2 name,location office1,address
name,location office1,address
why is this happeing ? i know i can filter array_unique using php after i fetch row, but what am i doing wrong ?

You want to use the distinct keyword in group_concat():
SELECT `t`.`id`, group_concat(distinct l.son) as sons,
group_concat(distinct l.id) as relsId,
group_concat( s.title ) as titles, group_concat( s.value ) as vals,
`t`.`name`, `t`.`type`, group_concat(s.id) as sid

Related

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.

Order By (from value on another DB)

i have a little probleme and i not found a solution.
i have 2 database > Name and Category
in the DB name its like :
ID NAme Cat_Id
1 Viskor 2
2 House 1
3 mouse 1
4 Charlie 2
5 One 3
and category db is :
ID Cat_Name
1 Word
2 User
3 Number
how is possible to display the list name order by name ASC from my category db?
actually i only can order by Cat_ID but is not alphabetic.
sory for my basic english and mistake ^^
SELECT * FROM name n INNER JOIN category c ON n.Cat_Id = c.ID ORDER BY cat_Name ASC
SELECT (YOUR_REQUIRED_SET_OF_FIELDS)
Try this one sir:
SELECT n.ID, n.NAme, n.Cat_Id, CAT_NAME
FROM Name n
INNER JOIN Category c
ON n.ID=c.ID ORDER BY c.NAme ASC;

MySQL Group by category limit N from each category

TABLE
id title category
1 hello1 1
2 hello2 2
3 hello3 1
Query
select *
from videos
where category in
(
select category
from videos
group by
category
having
count(*) < 3
ORDER BY RAND()
)
my goal is to get 2 titles from each category in a random order
also I want to fetch records in this manner
category1
title1
title2
category2
title1
title2
The below query gives no more than two random rows from each category:
SELECT title, category
FROM (
SELECT v.*,
if( category = #last_cat,
if( #last_cat:=category, #x:=#x+1,#x:=#x+1),
if( #last_cat:=category, #x:=0,#x:=0)
) x
FROM (SELECT #last_cat:=-9876, #x:=-91234) x,
(SELECT * FROM videos ORDER BY category, rand()) v
) x
WHERE x < 2
demo: http://sqlfiddle.com/#!2/59cf9/8
UPDATED
Please try this updated query (SQL Fiddle - http://sqlfiddle.com/#!2/de35bb/9):
select videos.*
from videos
where
(
select COUNT(vid.id)
from videos AS vid
WHERE videos.category = vid.category
) <= 2
ORDER BY
videos.category, RAND()
I've managed to find the solution on SO here:
Using LIMIT within GROUP BY to get N results per group?
in which answer points to the article
How to select the first/least/max row per group in SQL
where author describes a few techniques of performing such task.
The above query was built upon an example provided in the second article, but there are other forms of solving this problem.

Fetch data from mapping table if the condition matches in multiple rows

product_id property_id
1 2
1 5
2 2
3 5
I have a mapping table as above. I want to get only product with id =1 if product_id in (2,5). i.e. I want to fetch data if the table contains both 2,5 not the data if it is with property_id only 2 or 5
select group_concat(distinct product_id) product_ids from table where property_id in (2,5)
UPDATE:
The property_id in can be property_id in(2,5,....). I get output from form as 2,5,.... and so on. Its not just for the single case. I just want the output if the condition in property_id in matches the whole series.
This how it could be done
select
product_id from
table_name
where property_id in (2,5)
group by product_id
having count(*) = 2
All you need to change having count(*) = 2 to the number of items inside IN() , right now its 2 and if you are looking at 3 property id then it will be 3 and so on.
select distinct a.product_id
from table a, table b
where a.product_id = b.product_id
and a.property_id = 2
and b.property_id = 5

SQL select all using JOIN

I'm using this query to collate two sets of results but I now need to use JOIN instead of UNION to get the second part of the data from another table.
However I need quite a lot of fields and can't seem to find a way to maintain the use of SELECT * when using JOIN.
mysql_query("SELECT * FROM table.products WHERE category='$cat' GROUP BY product_id ORDER BY id UNION ALL SELECT * FROM table.products WHERE type='red' GROUP BY product_id ");
Table - products
product_id | title | category | id
0 one home 10
1 two home 11
1 two - a home 12
2 three work 13
Table - product_details
product_id | type | size |
0 blue S
1 blue M
1 red L
Ultimately I need to list every product in the first table for a given category e.g home,
as there is sometimes two entries or more for a single product id, I need to only select one row for each product id value. I also need to join the second table so I can get the size info, however I must be able to get the size info by preferring a type e.g red.
So for this example I would get a list like:
product_id | title | category | type | size
0 one home blue S
1 two home red L
This excludes product_id 2 as it's not in the home category, the first entry for product_id equaling 1 is selected because of the GROUP BY and ORDER BY and the information on size for product_id 1 is L because it is of type red not blue.
Assuming you are using MySQL, you want a join with an aggregation or aggressive filtering. Here is an example using join and aggregation:
select p.product_id, p.title, p.category,
substring_index(group_concat(pd.type order by pd.type = 'red' desc, pd.type), ',', 1) as type,
substring_index(group_concat(pd.size order by pd.type = 'red' desc, pd.type), ',', 1) as size
from products p join
product_details pd
on p.product_id = qpd.product_id
where p.category = 'home'
group by p.product_id;
The expression substring_index(group_concat(. . .)) is choosing one type (and one size) with precedence given to the red type.
Your query can be simplified like below since you are using the same table table.products. Not sure why you need to UNION them.
SELECT * FROM table.products
WHERE category='$cat'
and type='red'
GROUP BY product_id
EDIT:
With your edited post, the query should look like
select p.product_id,p.title,p.category,q.type,q.size
from products p join product_details q
on p.product_id = q.product_id
where p.category = 'home'
and q.type = 'red'

Categories