I’m attempting to build a PHP based web software and I came across a problem that I do not know the solution’s syntax for.
Basically, I have two tables:
+-------------+ +---------------+
| Certs | | Clients |
+-------------+ +---------------+
| userID | | eID |
| prodID | | prods |
| prodName | +---------------+
+-------------+
Here, every product an individual buys is stored by his unique userID and the product’s unique prodID.
Clients are like sellers who has different Ids themselves and prods which is a string of comma deli-mitered product IDs.
Example rows in the certs table would be like:
userID | prodID | prodName
------------------------------
9000 | 42 | Pen
4234 | 54 | Pencil
9000 | 54 | Pencil
An example client row would be like:
eID | prods
-------------
595 | 42,54
Now, I need to form a query that returns back all userIDs that have purchased all products of a particular seller.
Eg, for seller ID 595 it should return 9000, as userID 9000 has bought both 42 and 54.
Table structure can be modified for convenience however I cannot create a normalized list of products tied to their seller due to other technicalities.
Any help would be much appreciated! Thanks~
Note: Another way to put it is to keep the list of prods of a seller in a result type array.
Then SELECT prodID FROM certs WHERE userID = x
And finally check if, the result array of prodID has all elements of array prods.
Try this solution:
How it works:
What this does is append onto each row the count of the number of prodIDs that a particular seller has. We calculate it by taking the string length of the CSV list and substracting the length of the same CSV list but without commas, and add one to the difference. Example:
String length of “
54,234,436” is 10.Replace the commas:
String length of “
54234436” is 8.So then (10-8)+1 = 3.
Three items in the list.
We use
FIND_IN_SETas a join condition betweencertsandclientsto determine whether or not theprodIDexists within the CSVprodslist.FIND_IN_SETbasically returns the 1-based index position of a particular item in a CSV list. For example:will return
3because54exists as the third item in the list. We only need to check if it exists within the list for the join condition, so we just check if it’s > 0. If the item is not in the CSV list, it will return 0.Once we have the cartesian-joined count of products of a particular client, and the tables joined, the intermediate result-set would look something like this:
Each of these rows satisfied the join condition.
We then group by the
userIDto count the number of rows peruserID. Since 9000 has the same number of rows as the repeating value inc.prodcnt, that row is returned. userID4234is fitlered out because only one row satisfied the join condition.