Reputation: 13213
I am struggling to come up with the SQL query to find the all the products accessible to user under a particular division.
A division can have many products.
Division table has division_id
and division_name
.
Product table has product_id
, product_name
and division_id
.
I have another table called UserProducts where I have columns like
user_id
, division_id
and product_id
.
In the UI part while assigning products to user, division is selected first and then based on selected division products are populated.
In addition to the products from products table, the product drop down has one more option called as ALL.
When ALL option from product is selected all products under the division are assigned to the user.
But in the User products I do not enter entry for all the products. It has only one entry like
user_id = 1, division_id = 1 and product_id = -1
where -1 says its ALL products under division_id = 1
Also user can have access to many divisions. So User can have access to all products under division A but only two products under divison B.
Now, with this schema how do I get all the products accessible to user under division?
EDIT 1
I will have user id and product id as inputs and i would want to get all the products accessible to given user under given division.
Input : user_id, division_id output : List of all products by user_id and division_id
Please help.
Upvotes: 0
Views: 644
Reputation: 77707
SELECT DISTINCT
p.product_id,
p.whatever
FROM UserProducts up
INNER JOIN Product p ON up.product_id IN (-1, p.product_id)
WHERE up.user_id = @user_id
AND up.division_id = @division_id
Upvotes: 0
Reputation: 57053
SELECT product_id, product_name and division_id
FROM Products AS P
WHERE EXISTS (
SELECT *
FROM UserProducts AS U
WHERE U.division_id = P.division_id
AND U.product_id = -1
)
UNION
SELECT product_id, product_name and division_id
FROM Products AS P
WHERE EXISTS (
SELECT *
FROM UserProducts AS U
WHERE U.division_id = P.division_id
AND U.product_id = P.product_id
);
Upvotes: 1
Reputation: 340
This schema is not recommended as it would propose complexities later. For example if a user has all the products in 1 division but then one of the products is revoked, you will have to remove -1 entry and replace with the remaining assigned products.
However staying with this schema you will need to fetch the products via a Stored Procedure which checks if the value is -1 then pass all the products otherwise just the products that are assigned.
Create PROCEDURE [dbo].[sp_UserProductsbyDivision]
@Division as nvarchar(50),
@User as int output
AS
BEGIN
SET @AllProductsFlag=(select min(product_id) from UserProducts where user_id=@user and division_ID=@Division)
if @AllProductsFlag=-1
Begin
--Select ALL products in that divsion
Select @User, Products.Product_ID from Products where division_id=@division
End
Else
Begin
Select UserProducts.User_ID, Product_ID from UserProducts where User_ID=@User and Division_ID = @Division
End
END
Sorry I haven't been able to create the actual schema and test this but I think this should give you an idea. Debug as necessary!
Upvotes: 0
Reputation: 324
This should do it:
SELECT *
FROM user_products up
JOIN products p ON up.division_id = p.division_id AND (up.product_id = p.product_id OR up.product_id = -1)
WHERE up.user_id = ?????
AND up.division_id = ????
We join from the user_products table onto the products table where either both the division_id and product_id matches, or the division_id matches and the product_id is -1 (thus returning all corresponding products for that division). And finally at the end we restrict to a particular user_id and division id. Simply change the last two lines to change your inputs for example if you wanted to restrict by product instead of division swap: up.division_id = ???? for up.product_id = ????
Upvotes: 0