473,480 Members | 1,531 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Elegant way of getting multiple results

PhilOfWalton
1,430 Recognized Expert Top Contributor
I have a table with 5 Yes/No fields Mon, Tue, Wed, Thu, Fri.
I want the following results from a query.

If all 5 fields are True "Any day"
If all 5 fields ate False "" - Blank
If say Mon, Wed & Thu are True "Monday or Wednesday or Thursday"

I can obviously do it with a bit of code, but is there a way to do it within a Query?

Thanks

Phil
Jul 10 '16 #1
15 973
zmbd
5,501 Recognized Expert Moderator Expert
Expand|Select|Wrap|Line Numbers
  1. SELECT
  2.    Switch(Condition1,Result1,Condition2,Result2)
  3.       AS DaysSelected
  4. FROM Table;
The result# can be a calculated value...

Really not sure why you would build a table like this as it may break the rules of normality.

Also as it the IIF() the Switch() (Syntax) evaluatates all of the conditions and the results clauses; thus, if there's an error in any of the conditionals or results the whole thing will fail and it can be slow on large datasets.
Jul 10 '16 #2
PhilOfWalton
1,430 Recognized Expert Top Contributor
Thanks, Z, but switch only returns one result (the first true condition that is found)

I am looking for if Mon, Tue & Thu are all true, to return 3 values

I have gone it, but it's not pretty.

Expand|Select|Wrap|Line Numbers
  1. SELECT TblSpecialService.SPecialSeviceID, TblSpecialService.DMon, TblSpecialService.DTue, TblSpecialService.DWed, TblSpecialService.DThurs, TblSpecialService.DFri, 
  2. IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf([DMon]=True,"Monday or ")) AS Expr2, IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf([DTue]=True,"Tuesday or ")) AS Expr3, IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf([DWed]=True,"Wednesday or ")) AS Expr4, IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf([DThurs]=True,"Thursday or ")) AS Expr5, IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf([DFri]=True,"Friday or ")) AS Expr6, [expr2] & [expr3] & [expr4] & [expr5] & [expr6] AS Expr7, IIf([DMon]=False Or [DTue]=False Or [DWEd]=False Or [DThurs]=False Or [DFri]=False,IIf(Not IsNull([Expr7]),Left([Expr7],Len([Expr7])-3)),"Any Day") AS Expr8
  3. FROM TblSpecialService;
  4.  
Phil
Jul 10 '16 #3
zmbd
5,501 Recognized Expert Moderator Expert
Post#2 ... The result# can be a calculated value...
Then you set something like (using field Monday = [M] etc..):
Expand|Select|Wrap|Line Numbers
  1. Case1:
  2. (([M]=true) AND ([T]=True) AND ([W]=True) 
  3.    AND ([R]=True) AND ([F]=True))
  4. Result1:
  5. "AnyDay"
  6.  
  7. Case2:
  8. (([M]=False) AND ([T]=False) AND ([W]=False) 
  9.    AND ([R]=False) AND ([F]=False))
  10. Result2:
  11. ""
  12.  
  13. Case3
  14. (([M]=true) OR ([T]=True) OR ([W]=True) 
  15.    OR ([R]=True) OR ([F]=True))
  16. Result3:
  17. (iif([M]=true,":M:","" )+iif([T]=true,":T:","")
  18.    +iif([W]=true,":W:","")+iif([R]=true,":R:","")
  19.    +iif([F]=true,":F:",""))
  20.  
Of course you can insert something else instead of colons and with propagation of nulls most of the separators can be vanished.

Works quite nicely in my test database


; however, it still begs the question about normalization.
Attached Images
File Type: jpg 966788SwitchWCalcResult.JPG (26.0 KB, 220 views)
Jul 10 '16 #4
PhilOfWalton
1,430 Recognized Expert Top Contributor
Thanks, that looks great, Much more elegant than my solution

Phil
Jul 10 '16 #5
ADezii
8,834 Recognized Expert Expert
  1. let's assume you have the following Table named tblTest:
    Expand|Select|Wrap|Line Numbers
    1. PK    Mon    Tue    Wed    Thu    Fri
    2. 1    Yes    Yes    Yes    Yes    Yes
    3. 2    No    No    No    No    No
    4. 3    Yes    Yes    No    No    No
    5. 4    Yes    Yes    Yes    No    No
    6. 5    Yes    No    Yes    No    Yes
    7. 6    Yes    Yes    No    Yes    No
    8. 7    No    Yes    Yes    No    No
    9. 8    No    No    No    Yes    Yes
    10. 9    Yes    Yes    Yes    Yes    No
    11. 10    No    Yes    Yes    Yes    Yes
    12. 11    No    No    Yes    Yes    No
    13. 12    Yes    No    No    No    Yes
    14. 13    No    Yes    No    Yes    Yes
    15. 14    No    Yes    No    No    No
    16. 15    No    No    Yes    No    No
    17. 16    No    No    No    Yes    No
    18. 17    Yes    Yes    No    No    Yes
  2. Create the following Query that uses a Calculated Field to generate the appropriate Results:
    Expand|Select|Wrap|Line Numbers
    1. SELECT tblTest.PK, tblTest.Mon, tblTest.Tue, tblTest.Wed, tblTest.Thu, tblTest.Fri, fCheckAvailability([Mon],[Tue],[Wed],[Thu],[Fri]) AS Availability
    2. FROM tblTest;
  3. Function Definition:
    Expand|Select|Wrap|Line Numbers
    1. Public Function fCheckAvailability(blnMon As Boolean, blnTue As Boolean, blnWed As Boolean, _
    2.                                    blnThu As Boolean, blnFri As Boolean) As String
    3. Dim strBuild As String
    4.  
    5. 'Eliminate the extremes first
    6. If blnMon And blnTue And blnWed And blnThu And blnFri Then
    7.   fCheckAvailability = "Any Day"
    8.     Exit Function
    9. 'ElseIf Not (blnMon And blnTue And blnWed And blnThu And blnFri) Then
    10. ElseIf Not blnMon And Not blnTue And Not blnWed And Not blnThu And Not blnFri Then
    11.   fCheckAvailability = "No Days"
    12.     Exit Function
    13. End If
    14.  
    15. If blnMon Then strBuild = strBuild & "Monday Or "
    16. If blnTue Then strBuild = strBuild & "Tuesday Or "
    17. If blnWed Then strBuild = strBuild & "Wednesday Or "
    18. If blnThu Then strBuild = strBuild & "Thursday Or "
    19. If blnFri Then strBuild = strBuild & "Friday Or "
    20.  
    21. fCheckAvailability = Left$(strBuild, Len(strBuild) - 4)
    22. End Function
  4. Query after execution:
    Expand|Select|Wrap|Line Numbers
    1. PK    Mon    Tue    Wed    Thu    Fri    Availability
    2. 1     Yes    Yes    Yes    Yes    Yes    Any Day
    3. 2     No    No    No    No    No        No Days
    4. 3     Yes    Yes    No    No    No         Monday Or Tuesday
    5. 4     Yes    Yes    Yes    No    No       Monday Or Tuesday Or Wednesday
    6. 5     Yes    No    Yes    No    Yes    Monday Or Wednesday Or Friday
    7. 6     Yes    Yes    No    Yes    No     Monday Or Tuesday Or Thursday
    8. 7     No    Yes    Yes    No    No    Tuesday Or Wednesday
    9. 8     No    No    No    Yes    Yes    Thursday Or Friday
    10. 9     Yes    Yes    Yes    Yes    No     Monday Or Tuesday Or Wednesday Or Thursday
    11. 10    No    Yes    Yes    Yes    Yes    Tuesday Or Wednesday Or Thursday Or Friday
    12. 11    No    No    Yes    Yes    No    Wednesday Or Thursday
    13. 12    Yes    No    No    No    Yes     Monday Or Friday
    14. 13    No    Yes    No    Yes    Yes    Tuesday Or Thursday Or Friday
    15. 14    No    Yes    No    No    No      Tuesday
    16. 15    No    No    Yes    No    No      Wednesday
    17. 16    No    No    No    Yes    No     Thursday
    18. 17    Yes    Yes    No    No    Yes    Monday Or Tuesday Or Friday
P.S. - I do apologize for the poor formatting - running out the door and had no time to do so properly. You can also download the Demo if you like.
Attached Files
File Type: zip Demo.zip (33.0 KB, 72 views)
Jul 10 '16 #6
PhilOfWalton
1,430 Recognized Expert Top Contributor
Again that is sweet, but I have always found calling functions from queries slows things down, hence my earlier remark about avoiding VBA.

It's probably a new topic, but what is your experience of the speed using built in functions against "bespoke" functions?

Phil
Jul 10 '16 #7
ADezii
8,834 Recognized Expert Expert
what is your experience of the speed using built in functions against "bespoke" functions?
  1. To be perfectly honest, I have never dealt with such a large number of Records whereas the differences between the two approaches would be that significant.
  2. Personally, I find the use of multiple IIf() Constructs, which appears to be warranted here, to be very confusing and not very intuitive at all. I would easily sacrifice some processing time rather than deal with them. Again, only my personal opinion.
Jul 10 '16 #8
zmbd
5,501 Recognized Expert Moderator Expert
ADezii, agreeded, nested IIF() can be a nightmare to handle and it is the main reason I suggested the Switch() to avoid the nested IIF(); thus requiring on the simpler string of IIF() for the final condition result.

PhilOfWalton as with ADezii, I have smaller databases in Access; thus, I've not seen very much difference between custom user functions and the built in functions. With that said, I still try to stay with those that are native to Access or to the SQL when possible.
Jul 11 '16 #9
PhilOfWalton
1,430 Recognized Expert Top Contributor
Am going along with ADezii's solution, but want to modify it, as I use the same routine in a couple of places.

So I have modified the code to
Expand|Select|Wrap|Line Numbers
  1. Public Function fCheckAvailability(Typ As Byte, Flds As Variant) As String
  2.  
  3.     Dim strBuild As String
  4.     Dim DaysArray(1, 7) As String
  5.     Dim i As Integer, j As Integer
  6.     Dim ChrsToCut As Integer
  7.  
  8.     DaysArray(0, 0) = "No Day"
  9.     DaysArray(0, 1) = "Monday Or "
  10.     DaysArray(0, 2) = "Tuesday Or "
  11.     DaysArray(0, 3) = "Wednesday Or "
  12.     DaysArray(0, 4) = "Thursday Or "
  13.     DaysArray(0, 5) = "Friday Or "
  14.     DaysArray(0, 6) = "Any Day "
  15.     DaysArray(0, 7) = "4"
  16.  
  17.     DaysArray(1, 0) = "No Time"
  18.     DaysArray(1, 1) = "08:00 to 10:00  Or  "
  19.     DaysArray(1, 2) = "10:00 to 12:00  Or  "
  20.     DaysArray(1, 3) = "12:00 to 2:00  Or  "
  21.     DaysArray(1, 4) = "2:00 to 4:00  Or  "
  22.     DaysArray(1, 5) = "4:00 to 6:00  Or  "
  23.     DaysArray(1, 6) = "Any Time "
  24.     DaysArray(1, 7) = "6"
  25.  
  26.     ' Eliminate the extremes first
  27.     For i = 0 To 4
  28.         If Flds(i) = True Then
  29.             j = j + 1
  30.         End If
  31.     Next i
  32.  
  33.     If j = 0 Then                           ' No true found
  34.         fCheckAvailability = DaysArray(Typ, 0)
  35.         Exit Function
  36.     End If
  37.  
  38.     If j = 5 Then                           ' All true found
  39.         fCheckAvailability = DaysArray(Typ, 6)
  40.         Exit Function
  41.     End If
  42.  
  43.     For i = 0 To 4
  44.         If Flds(i) = True Then
  45.             strBuild = strBuild & DaysArray(Typ, i + 1)
  46.         End If
  47.     Next i
  48.  
  49.     ChrsToCut = CInt(DaysArray(Typ, 7))
  50.  
  51.     fCheckAvailability = Left$(strBuild, Len(strBuild) - ChrsToCut)
  52.  
  53. End Function
  54.  
This bit of code runs the routine and produced spot on results
Expand|Select|Wrap|Line Numbers
  1. Sub Test()
  2.  
  3.     Dim Arr() As Variant
  4.     Dim Typ As Byte             ' 0 for days, 1 for times
  5.  
  6.     Typ = 1
  7.     ReDim Arr(5)
  8.     Arr = Array(0, -1, -1, 0, -1)
  9.     Debug.Print fCheckAvailability(Typ, (Arr))
  10.  
So my problem is running the fCheckAvailability from a query.

The query is
Expand|Select|Wrap|Line Numbers
  1. SELECT SPecialSeviceID,DMon, DTue,DWed,DThurs, DFri,
  2.  fCheckAvailability(0,Array([DMon],[DTue],[DWed],[DThurs],[DFri])) AS Availability
  3. FROM TblSpecialService;
  4.  
All I get in the Availablility field is #Error, and the fCheckAvailability procedure never gets run (Breakpoint on first line never gets highlighted)

Do what is the correct version of
fCheckAvailability(0,Array([DMon],[DTue],[DWed],[DThurs],[DFri]))

Thanks

Phil
Jul 11 '16 #10
ADezii
8,834 Recognized Expert Expert
  1. Please bear with me since I am at work where Access is not available so I am duplicating the functionality as best as I can in Excel
  2. To be honest, I do not think that your approach will work, namely passing the Field Values within an Array to the fCheckAvailability() Function.
  3. What I "think" will work is to pass the actual Field Values ([DMon],[DTue],[DWed],[DThurs],[DFri]) to the fCheckAvailability_2() Function along with the Typ Argument.
  4. Typ will be passed by itself while the remaining Arguments representing the Days of the week will be passed to the Function where they will be integrated into a ParamArray and processed accordingly.
  5. Revised Function definition:
    Expand|Select|Wrap|Line Numbers
    1. Public Function fCheckAvailability_2(Typ As Byte, ParamArray Flds() As Variant) As String
    2. Dim strBuild As String
    3. Dim DaysArray(1, 7) As String
    4. Dim i As Integer, j As Integer
    5. Dim ChrsToCut As Integer
    6.  
    7. DaysArray(0, 0) = "No Day"
    8. DaysArray(0, 1) = "Monday Or "
    9. DaysArray(0, 2) = "Tuesday Or "
    10. DaysArray(0, 3) = "Wednesday Or "
    11. DaysArray(0, 4) = "Thursday Or "
    12. DaysArray(0, 5) = "Friday Or "
    13. DaysArray(0, 6) = "Any Day "
    14. DaysArray(0, 7) = "4"
    15.  
    16. DaysArray(1, 0) = "No Time"
    17. DaysArray(1, 1) = "08:00 to 10:00  Or  "
    18. DaysArray(1, 2) = "10:00 to 12:00  Or  "
    19. DaysArray(1, 3) = "12:00 to 2:00  Or  "
    20. DaysArray(1, 4) = "2:00 to 4:00  Or  "
    21. DaysArray(1, 5) = "4:00 to 6:00  Or  "
    22. DaysArray(1, 6) = "Any Time "
    23. DaysArray(1, 7) = "6"
    24.  
    25. ' Eliminate the extremes first
    26. For i = 0 To 4
    27.   If Flds(i) = True Then
    28.     j = j + 1
    29.   End If
    30. Next i
    31.  
    32. If j = 0 Then                           ' No true found
    33.   fCheckAvailability_2 = DaysArray(Typ, 0)
    34.     Exit Function
    35. End If
    36.  
    37. If j = 5 Then                           ' All true found
    38.   fCheckAvailability_2 = DaysArray(Typ, 6)
    39.     Exit Function
    40. End If
    41.  
    42. For i = 0 To 4
    43.   If Flds(i) = True Then
    44.     strBuild = strBuild & DaysArray(Typ, i + 1)
    45.   End If
    46. Next i
    47.  
    48. ChrsToCut = CInt(DaysArray(Typ, 7))
    49.  
    50. fCheckAvailability_2 = Left$(strBuild, Len(strBuild) - ChrsToCut)
    51. End Function
    52.  
  6. Sample Test Call (works as intended):
    Expand|Select|Wrap|Line Numbers
    1. Dim Typ As Byte             ' 0 for days, 1 for times
    2.  
    3. Typ = 1
    4.  
    5. MsgBox fCheckAvailability_2(Typ, 0, -1, -1, 0, -1)
    6.  
  7. Revised SQL Statement (Field Values passed individually), which infortunately, I cannot test! (LOL):
    Expand|Select|Wrap|Line Numbers
    1. SELECT SPecialSeviceID,DMon, DTue,DWed,DThurs, DFri,fCheckAvailability(0, [DMon], [DTue], [DWed], [DThurs], [DFri]) As Availability FROM TblSpecialService;
  8. Let me know how this works out for you.
Jul 11 '16 #11
ADezii
8,834 Recognized Expert Expert
Just noticed an Error in the SQL Syntax above in Item# 7, it should be:
Expand|Select|Wrap|Line Numbers
  1. SELECT SPecialSeviceID,DMon, DTue,DWed,DThurs, DFri,fCheckAvailability_2(0, [DMon], [DTue], [DWed], [DThurs], [DFri]) As Availability FROM TblSpecialService;
Jul 11 '16 #12
PhilOfWalton
1,430 Recognized Expert Top Contributor
Thanks, cracked it !!!

the relevant bits are for the SQL are
Expand|Select|Wrap|Line Numbers
  1. fCheckAvailability(1,[DMon],[DTue],[DWed],[DThurs],[DFri]) AS Availability
  2.  
and
Expand|Select|Wrap|Line Numbers
  1. Public Function fCheckAvailability(Typ As Byte, ParamArray Flds() As Variant) As String
  2.  
Your help very much appreciated.

Phil



Phil
Jul 11 '16 #13
ADezii
8,834 Recognized Expert Expert
You are very welcome, Phil. Good luck with your Project.
Jul 11 '16 #14
zmbd
5,501 Recognized Expert Moderator Expert
Phil, please keep in mind:
Elegant way of getting multiple results ...
I can obviously do it with a bit of code, but is there a way to do it within a Query?
You asked for an "Elegant" and basically SQL solution and that is what I had provided, if you had wanted a VBA solution I could have had that in the first reply.
Adezii's code is brilliant, but not simple; however, appears to be better suited for your long-term goal... which I don't think could be easily accomplished with Access's-SQL (not without a few more tables :) if at all )
Jul 12 '16 #15
PhilOfWalton
1,430 Recognized Expert Top Contributor
Apologies for that.

I changed my mind after reading various posts indicating that people did not think there was a measurable difference in the time to run a stored procedure against a built in function.
The VBA approach gives more flexibility and can be called using different arguments.

Once again, thanks & apologies

Phil
Jul 12 '16 #16

Sign in to post your reply or Sign up for a free account.

Similar topics

7
3823
by: Dr John Stockton | last post by:
What are the best ways of returning multiple results from a subroutine ? I've been using ... return } which is inelegant. I'm used to Pascal's procedure X(const A, B : integer; var C, D :...
2
1863
by: Ringo Langly | last post by:
Hi all, I need to put multiple results in one field, but not sure how. Here's some sample code: select a.name, a.accountnum, a.ordernum, (select itemid from items where items_ordernum =...
2
1407
by: sjoshi | last post by:
I'm trying this simple query but getting multiple listings for change_number field SELECT c.Change_Number, c.Submission_Date, c.Short_Description, c.CurrentStatus, dlv.Name, s.Description,...
2
2361
by: Patrick Olurotimi Ige | last post by:
When i run the code below with stored proc :- I get only the first table results :-"templates" even if i fill the dataset with another table for example category,pages etc.. Any ideas? ...
0
1118
by: | last post by:
Is there any sample about getting the results from executing an exe using asp? Thanks for answering.
2
2562
kaleeswaran
by: kaleeswaran | last post by:
hi! i want to know ..how to getting multiple rows from the database using ajax.and i pass these value to the javascript.give me solution... ...
2
1349
by: Neosword | last post by:
Hi I have a problem with a WHERE clause, I have to compare a column value to a query that returns multiple results, I also tried to substitute the "=" for "IN" but didn't worked. Any help would be...
8
5195
Alireza355
by: Alireza355 | last post by:
I have two tables: table1: number explanation 10 something here 11 something here 12 something here 13 something...
7
3121
by: seegoon | last post by:
Hi guys. I'm trying to write some php so that, depending on the page displayed, a certain <div> will load a certain class, giving it a certain background image. I have it down in theory, but...
4
1206
by: Brad Galinson | last post by:
I have a long sql query that, among other things, accesses multiple tables with an inner join and some left outer joins. I am expecting it to give a single set of results but when it finds more than...
0
6908
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7087
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
5341
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4782
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4483
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
2995
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
563
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
182
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.