Complex NOT EXISTS MySQL query - To ignore multiple matches - php

Below is a snippet from a large query I am running which performs a search on a table full of products. This snippet excludes certain products from appearing in results unless it's overridden (a tag ID is specified eg.search criteria is made).
Here's a couple of tag ID's and their names:
Tag ID 576 = 'Santa'
Tag ID 123 = 'Christmas'
So basically the below will exclude all products in the 'tags_gifts_occasion_specific' table unless they have a tag ID of 576 ('Santa').
AND NOT EXISTS (
SELECT *
FROM tags_gifts_occasion_specific
WHERE tags_gifts_occasion_specific.tag_id != '576'
GROUP BY tags_gifts_occasion_specific.gift_id
)
Simple right....
But the problem is if the same product is in this table but has a different tag ID applied to it... eg it also is in there for the tag 'Christmas'.
Of course it would be easy to just add 'AND tags_gifts_occasion_specific.tag_id != '123', however the query doesn't know what additional ID's it shouldn't look for - only the one that has been searched for.
I have been playing around with something like the following but unsuccessfuly. I thought I could count the number of occurences of gift_id and if it was already found then ignore any further - any fresh input would be greatly appreciated.
AND NOT EXISTS (
SELECT * , COUNT( * ) AS no_gifts
FROM tags_gifts_occasion_specific
WHERE tags_gifts_occasion_specific.tag_id != '576'
HAVING no_gifts < 1
GROUP BY tags_gifts_occasion_specific.gift_id
)
** FURTHER DETAIL REGARDING ORDER BY BUG **
So the order by bug is as follows. If someone searches for 'wedding' & 'bridemaid' gifts, wedding or bridemaid gifts should be returned with matches for both showed first, then the rest based on popularity. This works for all searches that do not have gifts in the 'tags_gifts_occasion_specific' table.
SELECT gifts.affiliate_id, gifts.gift_id, gifts.gift_title, gifts.gift_price, gifts.gift_image, gifts.gift_slug
FROM gifts
LEFT JOIN tags_gifts_occasion_specific AS os ON gifts.gift_id = os.gift_id
LEFT JOIN tags_gifts ON tags_gifts.gift_id = gifts.gift_id
LEFT JOIN tags ON tags.id = tags_gifts.tag_id
LEFT JOIN popularity ON popularity.gift_id = gifts.gift_id AND popularity.tag_id = tags.id
WHERE published = '1' AND in_seekgifts = '1'
AND ( (tags_gifts.tag_id = '576' OR tags_gifts.tag_id = '340') )
AND NOT EXISTS (
SELECT * FROM tags_gifts_occasion_specific x WHERE x.gift_id = gifts.gift_id
AND NOT EXISTS(
SELECT * FROM tags_gifts_occasion_specific x1 WHERE x.gift_id = x1.gift_id AND ( tag_id IN (576) OR tag_id in (340) ) )
)
GROUP BY gifts.gift_id
ORDER BY COUNT(*) DESC , popularity.popularity DESC, gifts.gift_popularity DESC, gifts.gift_id DESC
Live example of results:
http://www.seekgifts.co.uk/wedding_bridesmaid/
What I think is happening is that it can see the products in the top are in the tags_gifts_occasion_specific table for multiple tags and is therefore ordering by the number of times it is found in this table. Not sure how to get round this one?

As far as I understand, there is a table with products, and there is a table with tags for each product.
And the query is expected to skip products that have some tag, and include products that don't have these tags.
For example:
Products
| PRODUCT_ID | PRODUCT_NAME |
|------------|--------------|
| 1 | Product 1 |
| 2 | Product 2 |
| 3 | Product 3 |
| 4 | Product 4 |
| 5 | Product 5 |
Tags
| PRODUCT_ID | TAG |
|------------|--------------|
| 1 | Santa |
| 1 | Christmas |
| 2 | Christmas |
| 3 | Santa |
| 4 | Christmas |
| 4 | Exclude |
| 4 | Dont exclude |
| 5 | Christmas |
| 5 | Dont exclude |
And we want to skip rpoducts, that have tags Santa and Exclude.
In the above example, we want to skip products 1, 3 and 4, and include products 2, 5.
We can do it using the following correlated subquery
SELECT * from products p
WHERE
NOT EXISTS(
SELECT 1 FROM tags t
WHERE t.product_id = p.product_id
AND t.tag IN ( 'Santa', 'Exclude' )
)
;
| PRODUCT_ID | PRODUCT_NAME |
|------------|--------------|
| 2 | Product 2 |
| 5 | Product 5 |
Here is a link to a working demo: http://sqlfiddle.com/#!2/d880d/4
EDIT
An example for your schema
Gifts
select * from `gifts`;
| GIFT_ID | GIFT_TITLE |
|---------|------------------------|
| 1 | Red Christmas stocking |
| 2 | Santa Clause Socks |
| 3 | 40th Birthday Mug |
| 4 | Red Bowl |
tags_gifts_occasion_specific
select * from `tags_gifts_occasion_specific`
order by gift_id, tag_id;
| TAG_ID | GIFT_ID |
|--------|---------|
| 3 | 2 |
| 4 | 2 |
| 4 | 3 |
| 3 | 4 |
This query gets all entries from tags_gifts_occasion_specific, except these ones for which exists a tag_id = 3
select * from `tags_gifts_occasion_specific` x
where not exists(
select 1 from `tags_gifts_occasion_specific` x1
where x.gift_id = x1.gift_id
and tag_id in ( 3 )
);
| TAG_ID | GIFT_ID |
|--------|---------|
| 4 | 3 |
Now we use the above query to exclude some records from gifts table:
select * from `gifts` g
where not exists(
select 1 from `tags_gifts_occasion_specific` x
where g.gift_id = x.gift_id
and not exists(
select 1 from `tags_gifts_occasion_specific` x1
where x.gift_id = x1.gift_id
and tag_id in ( 3 )
)
);
| GIFT_ID | GIFT_TITLE |
|---------|------------------------|
| 1 | Red Christmas stocking |
| 2 | Santa Clause Socks |
| 4 | Red Bowl |
| 5 | Red 40th Birthday Vase |
Here is a link to a demo: http://sqlfiddle.com/#!2/558422/5

Related

Fetch Products Count for specific week in mysql

I have 3 tables
Orders
id | name | order_date | total
------------------------------
1 | ABCD | 2017-03-29 | 60
2 | KJHS | 2017-03-29 | 80
3 | HGGG | 2017-03-30 | 90
item_orders
id | order_id | item_id
-----------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
items
id | item_name | desc | price |
---------------------------------
1 | Brown | jdsa | 20
Cardigan XL
---------------------------------
2 | Red Socks | sada | 30
---------------------------------
My Query which I have wrote is
SELECT orders.*, item_orders.item_id,items.item_name,items.description,items.price
FROM ((orders
INNER JOIN item_orders ON orders.id = item_orders.item_id)
INNER JOIN items ON item_orders.item_id = items.id)
WHERE WEEKOFYEAR(orders.order_date)=WEEKOFYEAR(NOW());
Now I wanted to bring item_count total from orders table of current week with its total.
Something like these shows current week stats
BrownCardigan XL 12 $200
Red Socks 15 $350
Something like these.
I am bringing data from orders table by above query and Now I am stuck of how to count the items from order table and sum of prices for the current week.
you could use aggreagation function and group by
SELECT items.item_name, sum(orders.total), sum(orders.total*items.price)
FROM orders
INNER JOIN item_orders ON orders.id = item_orders.item_id
INNER JOIN items ON item_orders.item_id = items.id
WHERE WEEKOFYEAR(orders.order_date)=WEEKOFYEAR(NOW()
GROUP BY items.item_name
;

mysql search title, description and multi rows tag (regarding conditions)

I want to realize a search similar to mysql search title, description and multi rows tag.
Here are my tables:
Books:
+----+-----------------------+-------------+
| id | name | description |
+----+-----------------------+-------------+
| 1 | Me Before You | [TEXT] |
| 2 | How To Win Friends... | [TEXT] |
| 3 | The Girl on the Train | [TEXT] |
| 4 | After You | [TEXT] |
| 5 | We Were Liars | [TEXT] |
+----+-----------------------+-------------+
Tags:
+----+-----------------------+
| id | tag |
+----+-----------------------+
| 1 | romance |
| 2 | thriller |
| 3 | fantasy |
| 4 | science fiction |
| 5 | drama |
| 6 | friends |
+----+-----------------------+
Books_tags:
+---------+--------+
| book_id | tag_id |
+---------+--------+
| 1 | 1 |
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
| 3 | 5 |
| 4 | 1 |
| 4 | 5 |
| 4 | 6 |
| 5 | 2 |
| 5 | 6 |
+---------+--------+
Here are some example searches and the desired results:
'romance' -> books 1, 4
'friends' -> books 2, 4, 5
'friends win' -> books 2
'fantasy' -> books 2, 3
'fantasy train' -> books 3
Before building the SQL query, a function checks every given keyword if it's even a tag at once. My problem is, for example, in this case:
Case: 3 /
Keywords: friends win /
Tags: friends
Query:
SELECT SQL_CALC_FOUND_ROWS
b.id, b.name,
MATCH(b.name) AGAINST('*friends* *win*' IN BOOLEAN MODE) as name_score,
MATCH(t.tag) AGAINST('friends' IN BOOLEAN MODE)as tag_score
FROM
books b
LEFT JOIN
books_tags bt ON bt.book_id = b.id
LEFT JOIN
tags t ON t.id = bt.tag_id
WHERE
MATCH(b.name) AGAINST('*friends win*' IN BOOLEAN MODE)
OR MATCH(t.tag) AGAINST('friends' IN BOOLEAN MODE)
GROUP BY
b.id
ORDER BY
name_score DESC, (tag_score + name_score) DESC
Results:
array (size=3)
0 => string '2' (length=1)
1 => string '4' (length=1)
2 => string '5' (length=1)
In this case, the keyword 'friends' already matches the title, so the condition must be reduced and should not search the tags anymore. How can I solve it?
Is this what you're after?...
Data set
DROP TABLE IF EXISTS books;
CREATE TABLE books
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,name VARCHAR(50) NOT NULL
,FULLTEXT(name)
) ENGINE = MyISAM;
INSERT INTO books VALUES
(1,'Me Before You'),
(2,'How To Win Friends...'),
(3,'The Girl on the Train'),
(4,'After You'),
(5,'We Were Liars');
DROP TABLE IF EXISTS tags;
CREATE TABLE tags
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,tag VARCHAR(20) NOT NULL
);
INSERT INTO tags VALUES
(1,'romance'),
(2,'thriller'),
(3,'fantasy'),
(4,'science fiction'),
(5,'drama'),
(6,'friends');
DROP TABLE IF EXISTS books_tags;
CREATE TABLE books_tags
(book_id INT NOT NULL
,tag_id INT NOT NULL
,PRIMARY KEY(book_id,tag_id)
);
INSERT INTO books_tags VALUES
(1,1),
(1,3),
(2,3),
(3,3),
(3,5),
(4,1),
(4,5),
(4,6),
(5,2),
(5,6);
Query and result
SELECT DISTINCT b.*
, MATCH(b.name) AGAINST('*friends* *win*' IN BOOLEAN MODE) name_score
FROM books b
LEFT
JOIN books_tags bt
ON bt.book_id = b.id
LEFT
JOIN tags t
ON t.id = bt.tag_id
AND t.tag IN ('friends','win')
WHERE t.id IS NULL;
+----+-----------------------+------------+
| id | name | name_score |
+----+-----------------------+------------+
| 1 | Me Before You | 0 |
| 2 | How To Win Friends... | 1 |
| 3 | The Girl on the Train | 0 |
| 4 | After You | 0 |
| 5 | We Were Liars | 0 |
+----+-----------------------+------------+
Ok, finally I wrote a function, that generates a working query for me. The function is very complex and depends on several user inputs. The solution is to concatenate t.tag and b.name. This is, how my WHERE-condition looks like and it work's fine for me:
... WHERE ap.active='yes'
AND (LOWER(CONCAT_WS(' ', IF(LENGTH(t.tag), t.tag, NULL), IF(LENGTH(b.name), b.name, NULL) )) REGEXP 'friends'
AND LOWER(CONCAT_WS(' ', IF(LENGTH(t.tag), t.tag, NULL), IF(LENGTH(b.name), b.name, NULL) )) REGEXP 'win')
GROUP BY b.id

divide column values (numbers) based on group by

First of all I am not really good with MySQL whatever experience I have I am putting it to make this query
In my query the main problem is with
left join subdealers as subdealer
ON
(
employees.Salesman1Number = subdealer.employee_number
OR employees.Salesman2Number = subdealer.employee_number
OR employees.Salesman3Number = subdealer.employee_number
)
I am trying to get the FrontGross, BackGross etc grouped by subdealer.group_name the problem is Saleman1Number & Salesman2Number might belong to same group_name and in the query below it counts them as two different Salesmen while what I want them to count as one in case the Salesman1Number, Saleman2Number and Salesman2Number belongs to same subdealer.group_name
For example: Salesman1Number belongs to group_name Fleet and Salesman2Number also belongs to Fleet
They both contributed to sell a single car. Now they both have half credit of what they sold and that credit goes to group_name Fleet as one, half from Salesman1Number and half from Salesman2Number
currently the query I wrote doesn't divide them in half depending on their group_name but count it as one from Salesman1Number
and one from Salesman2Number
SELECT count(core_leads.core_id) as leads,
count(new.id) as new,
count(used.id) as used,
IFNULL(SUM(profit.FrontGross) + SUM(finance.HoldbackAmount), 0) as FrontGross,
IFNULL(SUM(profit.BackGross) + SUM(profit.FinanceReserve), 0) as BackGross,
IFNULL(SUM(profit.TotalProfit), 0) as TotalProfit,
IFNULL(SUM(finance.HoldbackAmount), 0) as HoldbackAmount,
IFNULL(SUM(finance.Holdcheck), 0) as Holdcheck,
IFNULL(subdealer.group_name, 'Others') as group_name
from core_leads
inner join
(
select * from closed_deals
right join
(
select ContractDate, id as infoId, closed_deal_id
from closed_deal_infos
) as info
ON closed_deals.id = info.closed_deal_id
AND DATE(info.ContractDate) BETWEEN '2014-01-01' AND '2017-01-01'
) as closed
ON core_leads.core_id = closed.core_lead_id
AND core_leads.type != 'Unwind'
AND core_leads.type != 'Canceled'
left join closed_vehicles as used
ON closed.id = used.closed_deal_id
AND used.NewUsed = 'U'
left join closed_vehicles as new
ON closed.id = new.closed_deal_id
AND new.NewUsed = 'N'
left join closed_dealer_employees as employees
ON closed.id = employees.closed_deal_id
left join subdealers as subdealer
ON
(
employees.Salesman1Number = subdealer.employee_number
OR employees.Salesman2Number = subdealer.employee_number
OR employees.Salesman3Number = subdealer.employee_number
)
AND
(
subdealer.group_name = 'Fleet'
OR subdealer.group_name = 'Internet'
OR subdealer.group_name = 'Sales'
)
left join closed_profit as profit
ON closed.id = profit.closed_deal_id
left join closed_finance as finance
ON closed.id = finance.closed_deal_id
group by subdealer.group_name
This results this
While in the Fleet dept column name leads should be 38 instead of 40 because it is counting two different Salesmen whom belongs to same group_name as two
Let me know if I was not clear enough
To simplify your example i will use only two tables.
persons:
| personId | groupId |
|----------|---------|
| 1 | 1 |
| 2 | 2 |
| 3 | 2 |
| 4 | 3 |
| 5 | 4 |
| 6 | 5 |
activities:
| actId | person1Id | person2Id | person3Id | actValue |
|-------|-----------|-----------|-----------|----------|
| 1 | 1 | 2 | 3 | 1 |
| 2 | 1 | 2 | 4 | 10 |
| 3 | 5 | (null) | (null) | 100 |
A query which matches your problem would be:
select
p.groupId, count(a.actId) numActs, sum(a.actValue) sumVals, group_concat(a.actId) as acts
from activities a
left join persons p on (
a.person1Id = p.personId or
a.person2Id = p.personId or
a.person3Id = p.personId
)
group by p.groupId;
Result:
| groupId | numActs | sumVals | acts |
|---------|---------|---------|-------|
| 1 | 2 | 11 | 1,2 |
| 2 | 3 | 12 | 1,2,1 |
| 3 | 1 | 10 | 2 |
| 4 | 1 | 100 | 3 |
For the group with groupId=2 we have counted three activities (1,2,1). The Activity with actId=1 is counted twice because there are two persons from same group. To prevent that, we can define that a row for person2 should not be counted (should be filtered out) if person1 is from same group. And a row for person3 should not be counted if person1 or person 2 is from the same group. This can be done in the WHERE clause with dependent selects:
select
p.groupId, count(a.actId) numActs, sum(a.actValue) sumVals, group_concat(a.actId) as acts
from activities a
left join persons p on (
a.person1Id = p.personId or
a.person2Id = p.personId or
a.person3Id = p.personId
)
where (p.personId = a.person1Id
) or (
p.personId = a.person2Id and
p.groupId not in (select groupId from persons where personId = a.person1Id)
) or (
p.personId = a.person3Id and
p.groupId not in (select groupId from persons where personId in (a.person1Id, a.person2Id))
)
group by p.groupId;
Result:
| groupId | numActs | sumVals | acts |
|---------|---------|---------|------|
| 1 | 2 | 11 | 1,2 |
| 2 | 2 | 11 | 1,2 |
| 3 | 1 | 10 | 2 |
| 4 | 1 | 100 | 3 |
http://sqlfiddle.com/#!9/604a5/1
Note: If possible - you should consider to normalize your tables.

Matching column names in DB using JOIN NULL values

I am trying to create an "eBay" style category menu where when the user selects an item from a multiselect field it will add a new multiselect with any sub categories and if the sub category contains sub categories add a new multi select with the sub sub categories.
I have this mostly working but I am having trouble with the database side of things. I have a main table called categories that contains two columns CatID and Category. There are three rows in the categories table "Motorcycles", "Powersports" and "Parts & Accessories"
When a user selects Motorcycles it should create a new multi select and bring up Motorcycle Brands. If on the other hand the user selects Powersports it should create a new multi dropdown and list Powersport vehicle types "Dirtbike", "PWC", "Snowmobile" etc. Which upon selecting one of those will bring up a Powersports->Vehicle Type->Brand multiselect.
The problem is I don't know how to reference all of this information properly in the database.
For example:
Main Categories(categories)
+-------+---------------------+
| CatID | Category |
+-------+---------------------+
| 1 | Motorcycles |
| 3 | Parts & Accessories |
| 2 | Powersports |
+-------+---------------------+
Motorcycles Sub Category: (motorcycle_brands)
+-------+-------+-------------------------+
| CatID | SubID | SubName |
+-------+-------+-------------------------+
| 1 | 1 | American Classic Motors |
| 1 | 2 | American Ironhorse |
| 1 | 3 | Aprilia |
| 1 | 4 | Benelli |
| 1 | 5 | Big Dog |
+-------+-------+-------------------------+
Power Sports Sub Category: (powersport_categories)
+-------+-------+--------------------------------+----+
| CatID | SubID | SubName | ID |
+-------+-------+--------------------------------+----+
| 2 | 1 | ATVs | 1 |
| 2 | 2 | Dune Buggies / Sand Rails | 2 |
| 2 | 3 | Go Karts: High-Performance | 3 |
| 2 | 4 | Personal Watercraft | 4 |
| 2 | 5 | Powersport Vehicles Under 50cc | 5 |
+-------+-------+--------------------------------+----+
So if I run the following command:
SELECT * FROM categories C
LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID
LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID
WHERE C.CatID = 1 LIMIT 5;
I get this:
+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+
| CatID | Category | CatDBTable | CatID | SubID | SubName | CatID | SubID | SubName | ID |
+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+
| 1 | Motorcycles | motorcycle_brands | 1 | 1 | American Classic Motors | NULL | NULL | NULL | NULL |
| 1 | Motorcycles | motorcycle_brands | 1 | 2 | American Ironhorse | NULL | NULL | NULL | NULL |
| 1 | Motorcycles | motorcycle_brands | 1 | 3 | Aprilia | NULL | NULL | NULL | NULL |
| 1 | Motorcycles | motorcycle_brands | 1 | 4 | Benelli | NULL | NULL | NULL | NULL |
| 1 | Motorcycles | motorcycle_brands | 1 | 5 | Big Dog | NULL | NULL | NULL | NULL |
+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+
Notice all the NULL values at the end. Is there a way to get rid of these null values? It is causing other problems in my code because when it returns this array back to my PHP script the SubID and SubName array fields are blank since it goes with the last set which are NULL. However if I run the same query as above replacing 1 with 2 then I get the values I want back since they are not over written by duplicate column names.
Maybe I am going about this all wrong I was planning on having the same SubID and SubName columns in all of my tables for sub categories but it looks like it may cause me grief. The reason I did this is because otherwise I was having to write a separate query depending on what value was selected I wanted to have basically one query that would do it all essentially for each sub option. Is there any improvements here?
1) Try something like this (you should also check my other point below):
SELECT C.CatID, C.Category, C.CatDBTable, MB.SubID AS MbSubID, MB.SubName AS MbSubName, PC.SubID AS PcSubID, PC.SubName AS PcSubName, PC.ID AS PcID FROM categories C
LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID
LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID
WHERE C.CatID = 1 LIMIT 5;
2) Your database structure might be made better and more extensible (if you needed for exemple to add a 4th degree sub) if you used the following approach :
Have only one table name categories which has the following columns :
ID
parent_id (nullable)
depth
name
you will use it as follows:
"Motorcycles" which is a main category will have: (ID => 1, parent_id => null, depth => 0, name => Motorcycles)
"American Classic Motors" which is a sub of "Motorcycles" will have: (ID => 4, parent_id => 1, depth => 1, name => American Classic Motors)
"ATVs" which is a sub of "American Classic Motors" will have: (ID => 5, parent_id => 4, depth => 2, name => ATVs)
Try this:
SELECT C.CatID,C.Category,MB.CatID as MBCatID,MB.SubID as MBSubID,MB.SubName as MBSubName,IFNULL(PC.CatID,'') as PCCatID,IFNULL(PC.SubID,'') as PcSubID,IFNULL(PC.SubName,'') as PcSubName,IFNULL(PC.ID,'') as PCID FROM categories C
LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID
LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID
WHERE C.CatID = 1 LIMIT 5;
See the result in SQL Fiddle

Mysql limit the number of returned results based on the unique values from a single column

I have three tables,
Product_to_categories => contains two columns (Category_id, Product_id)
Product => contains a few columns (product_id, name, sku, ...)
categories => contains a few columns (category_id, name, ....)
I would like to get a result set for the first 10 unique category_id's joined with the product table, a category can have many product assigned to it, i want all products within one category returned, but i'd like to only get the products from the first 8 categories...
Current query:
SELECT p2c.category_id, p.pname, c.category_name
FROM product p LEFT JOIN product_to_category p2c
ON (p.product_id = p2c.product_id)
Left Join category c (p2c.category_id = c.category) LIMIT 0,8
Current output
catID | p.name | catName |<br/>
1 | docs | shoe<br/>
1 | bob | shoe<br/>
1 | mom | shoe<br/>
1 | cat | shoe<br/>
1 | dang | shoe<br/>
1 | kit | shoe<br/>
2 | pis | book<br/>
2 | jiz | book<br/>
Currently i only get the first 8 results regardsless, however i am looking to get the following output:
catID | p.name | catName |<br/>
1 | docs | shoe<br/>
1 | bob | shoe<br/>
1 | mom | shoe<br/>
1 | cat | shoe<br/>
1 | dang | shoe<br/>
1 | kit | shoe<br/>
2 | pis | book<br/>
2 | jiz | book<br/>
3 | docs | shirt<br/>
3 | bob | shirt<br/>
3 | mom | shirt<br/>
4 | cat | light<br/>
4 | dang | light<br/>
5 | kit | sound<br/>
6 | pis | mic<br/>
6 | jiz | mic<br/>
7 | docs | pen<br/>
7 | bob | pen<br/>
7 | mom | pen<br/>
7 | cat | pen<br/>
8 | dang | lace<br/>
8 | kit | lace<br/>
8 | pis | lace<br/>
8 | jiz | lace<br/>
i would like the resultset to contain results of all products that are assigned to the first 8 categories...
Please advise.
Thanks
Hadi
I'm a bit unsure why your query is starting from the product table, so I'm not going to - but aside from this, I think what you need is:
SELECT c.category_id, p.pname, c.category_name
FROM category c
INNER JOIN product_to_category pc ON c.category_id = pc.category_id
INNER JOIN product p ON pc.product_id = p.product_id
WHERE c.category_id in (SELECT TOP 8 category_id FROM Category)
ORDER BY 1, 2

Categories