Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 15:07:28
|
My table is like thisprofileID intsourceID intmin intmax intisFlag bitprofileID is a foreign keyprofileID + sourceID is a unique keysample data would look like thisprofileID sourceID min max isFlag--------------------------------------------- 100 1 5 10 0 100 2 5 10 0 100 3 8 10 0 101 2 5 10 0 101 3 0 10 0 102 1 0 20 1 102 4 0 20 1 103 1 5 10 0 103 2 5 10 0 103 3 8 10 0 103 4 0 20 1 I would like to match a specific set of rows and retrieve the profileID for them. Examples follow using above data layout:----Send 2 0 15 1 Returns: No match/null/empty whatever----Send 1 0 20 1 4 0 20 1 Returns: profileID 102----Send 1 5 10 0 2 5 10 0 3 8 10 0 Returns profileID 100 (and does not return profileID 103 even though this is a subset of it's data)----Alternative table structures are also welcome |
|
|
vijayisonly
Master Smack Fu Yak Hacker
1836 Posts |
Posted - 2009-07-09 : 15:12:20
|
quote: I would like to match a specific set of rows and retrieve the profileID for them.
The specific set of rows is in another table or a file? The "Send" in your sample ..what does it mean? |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2009-07-09 : 15:19:52
|
Create a temp table (called Send in my example) and load it with your Send data then join it: SELECT MyTable.ProfileIDFROM MyTableINNER JOIN Send ON MyTable.SourceID = Send.SourceID AND MyTable.Min = Send.Min AND MyTable.Max = Send.Max AND MyTable.IsFlag = Send.IsFlagGROUP BY MyTable.ProfileIDHAVING COUNT(*) = (SELECT COUNT(*) FROM Send) |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 15:20:08
|
| The specific set of rows would be supplied, say for instance a 2008 stored procedure that takes datatable.The examples are meant to work as a sort of black box from my perspective. The rows next to "Send" are the rows that are being supplied to whatever stored procedure/udf/query will do the matching. And "Return" is the answer I am expecting/would like to receive. |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 15:22:01
|
quote: Originally posted by Lamprey Create a temp table (called Send in my example) and load it with your Send data then join it:
Going to give this a shot, Thanks for the direction!I'm still open to other options too. I expect this kind of thing to happen "semi" often and I'd like the processing to not take a long time. |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 16:08:49
|
I'm using a table value parameter in a stored procedure, so far it seems to be behaving properly.Just to confirm; quote: Originally posted by LampreyHAVING COUNT(*) = (SELECT COUNT(*) FROM Send
Is the line that prevent matching a profile that contains the Send table as a subset? So if Send has 3 rows I only get back matches that also have 3 rows. |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2009-07-09 : 16:09:03
|
>> I expect this kind of thing to happen "semi" often Not that I can recalland Lampy, the code doesn't quite do it...seems to grab 103 as wellSET NOCOUNT ONGOCREATE TABLE myTable99( profileID int , sourceID int , [min] int , [max] int , isFlag bit)GOINSERT INTO myTable99(profileID, sourceID, [min], [max], [isFlag])SELECT 100, 1, 5, 10, 0 UNION ALLSELECT 100, 2, 5, 10, 0 UNION ALLSELECT 100, 3, 8, 10, 0 UNION ALLSELECT 101, 2, 5, 10, 0 UNION ALLSELECT 101, 3, 0, 10, 0 UNION ALLSELECT 102, 1, 0, 20, 1 UNION ALLSELECT 102, 4, 0, 20, 1 UNION ALLSELECT 103, 1, 5, 10, 0 UNION ALLSELECT 103, 2, 5, 10, 0 UNION ALLSELECT 103, 3, 8, 10, 0 UNION ALLSELECT 103, 4, 0, 20, 1GODECLARE @Send table ( sourceID int , [min] int , [max] int , isFlag bit)INSERT INTO @Send (sourceID, [min], [max], isFlag)SELECT 1, 5, 10, 0 UNION ALLSELECT 2, 5, 10, 0 UNION ALLSELECT 3, 8, 10, 0 SELECT t.ProfileID, COUNT(*) FROM MyTable99 tINNER JOIN @Send s ON t.SourceID = s.SourceID AND t.[Min] = s.[Min] AND t.[Max] = s.[Max] AND t.IsFlag = s.IsFlag GROUP BY t.ProfileID HAVING COUNT(*) = (SELECT COUNT(*) FROM @Send)GODROP TABLE myTable99GO Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxAdd yourself!http://www.frappr.com/sqlteam |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 16:13:38
|
| X002548, Thanks for putting it into sql code. In hindsight I should have done this for the examples to promote people's answers. Next time I will.happening "semi" often is a reference to the query being called often in my program. Basically anytime someone changes their profile it should check if they match someone else's profile.Thanks again to everyone that is helping! |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2009-07-09 : 16:15:34
|
| Good call, this is one of those things that you run into using the dimensional model in data warehousing, thus why I advocate not using a incomplete/flawed model. I know I have some code floating around that does this, let me take a look-see and get back to you.. |
 |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2009-07-09 : 16:17:50
|
| Just change the INNER JOIN to LEFT OUTER JOIN.. bah.. slow today.. :)EDIT: scratch that.. my brain is fried.. let me look for my code again.. |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 16:19:57
|
| In Lampy's answerChanging the INNER JOIN to LEFT JOIN produces the desired result. It allows the HAVING COUNT(*) = (SELECT COUNT(*) FROM @Send)to return COUNT(*) = 4 for profileID 103 instead of COUNT(*) = 3 being returned when using INNER JOIN.Guess I was a few seconds slower than Lampy :)Lampy,Please help me understand/find resources as to why this model is flawed/incomplete. This came from not wanting to store this profile data for each individual user. I am certainly open to information. |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2009-07-09 : 16:22:48
|
quote: Originally posted by trondaron In Lampy's answerChanging the INNER JOIN to LEFT JOIN produces the desired result. It allows the HAVING COUNT(*) = (SELECT COUNT(*) FROM @Send)to return COUNT(*) = 4 for profileID 103 instead of COUNT(*) = 3 being returned when using INNER JOIN.
That is just an artifact of the data. try this: SELECT*FROM ( SELECT ProfileID, COUNT(*) AS RowCnt FROM myTable99 GROUP BY ProfileID ) AS AINNER JOIN ( SELECT t.ProfileID, COUNT(*) AS RowCnt FROM MyTable99 t INNER JOIN @Send s ON t.SourceID = s.SourceID AND t.[Min] = s.[Min] AND t.[Max] = s.[Max] AND t.IsFlag = s.IsFlag GROUP BY t.ProfileID HAVING COUNT(*) = (SELECT COUNT(*) FROM @Send) ) AS B ON A.ProfileID = B.ProfileID AND A.RowCnt = B.RowCnt |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2009-07-09 : 16:27:16
|
| OK...so you live in Costa Rica....I wouldn't worry about it too muchHowever, when the "model" is being discussedYou should have a Parent table that describes the userThen a child table you join to, to find the properties about that userso what is it you are trying to doYou have some kind of profile and you want to find who fits those profiles?Not sure what you are trying to do?Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxAdd yourself!http://www.frappr.com/sqlteam |
 |
|
|
trondaron
Starting Member
13 Posts |
Posted - 2009-07-09 : 16:51:37
|
quote: Originally posted by X002548You should have a Parent table that describes the userThen a child table you join to, to find the properties about that userso what is it you are trying to doYou have some kind of profile and you want to find who fits those profiles?Not sure what you are trying to do?
User table; userID, name, password, viewProfileID, limitProfileID, and some other user specific data that will often be unique per UserlimitProfileID and viewProfileID are FK to a limitProfile and viewProfile table respectively which hold semi unique data. I expect every 100-200 users to have matching profiles.Source table; sourceID, webpageName, shortNameThis table gives an ID to webpage and defines some abbreviations that can be used to refer to the page.limitProfile table; limitProfileIDlimitProfileSettings table; limitProfileID, sourceID, min, maxA user with this limitProfileID will be able to enter values between min and max on the specified "source" or webpageviewProfile table; viewProfileIDviewProfileSettings table; viewProfileID, sourceID, showFooter, showHeaderA user with this viewProfileID will be shown or now shown header/footers on the specified "source" or webpageThere are additional variables and user tables, but this is a basic representation of what I am creating. I realize some of this may not be clear, I'll do my best to expand on whatever raises questions. |
 |
|
|
|
|
|
|
|