I have the following query that is not producing the expected results. I converted this from an Access query and there is a HAVING clause in the Access query that I cannot seem to replicate in my SQL. The HAVING clause contains the code relating to the field, Eval Date. I tried adding that code to a HAVING statement in my SQL, but it did not make a difference in the output. How can I properly group this query?
DECLARE
#CurrentYear smallint,
#CurrentMonth date,
#Period varchar(3),
#Division varchar(2)
SELECT
#CurrentYear = DATEPART(YY, GETDATE()),
#CurrentMonth = EOMONTH(GETDATE(), -1),
#Division = 'BT'
SELECT #Period = dd.FiscalPeriod
FROM dbo.DateDimension dd (NOLOCK)
WHERE dd.LastDayOfMonth = #CurrentMonth
SELECT
SupplierNumberBS = REPLACE(LTRIM(REPLACE(pm.[Suppl ID], '0', ' ')), ' ', '0'),
Period = #Period,
FY = #CurrentYear,
Division = #Division,
pm.Country,
pm.PCat,
PMCTValidation1 = pm.[Supplier Status PMCT] + pm.[ES (Supplier)],
pm.[Eval Date],
pm.[End Date],
pm.Evaluator,
PMCTEValuationStatus =
CASE
WHEN pm.[Eval Date] IS NOT NULL THEN 'Completed'
WHEN pm.[ES (Supplier)] = 'R' AND pm.[SEval (Project)] = 'R' THEN 'Overdue'
ELSE 'Upcoming'
END,
PMCTStarRating =
CASE
WHEN pm.Score IS NULL THEN 0
WHEN pm.Score >= 90 THEN 5
WHEN pm.Score >= 80 THEN 4
WHEN pm.Score > 70 THEN 3
WHEN pm.Score >= 50 THEN 2
ELSE 1
END,
pm.[Overdue Date],
pm.[Eval ID],
pm.[ES (Supplier)],
bb.BranchOffice,
bb.Zone,
pm.[Project ID],
pm.Score,
pm.NCC,
pm.[NCC Amount],
pm.PM,
SupplierNameBS = pm.[Suppl Name],
pm.Comment,
pm.[Comment Problem],
pm.Problem,
pm.Purchasing,
pm.Logistics,
pm.[Quality and EHS],
pm.Technology,
pm.[Devel Status],
OpenSupplierNCC = pm.[NCC 1]-[NCC Recovered],
pm.[NCC 1],
pm.[NCC Recovered],
pm.Name,
pm.[Root Cause],
pm.[Comment Action],
pm.Claim
FROM
dbo.BTPMCT pm (NOLOCK)
LEFT JOIN dbo.BTBuyerBranch bb (NOLOCK) ON pm.[Branch Number] = bb.BranchNumber
WHERE
pm.[Supplier Status PMCT] + pm.[ES (Supplier)] <> 'InactiveR'
AND
pm.Country = 'CA'
AND
pm.[Eval Date] >= DATEADD(MONTH, -14, GETDATE())
OR
pm.[Eval Date] IS NULL
GROUP BY
REPLACE(LTRIM(REPLACE(pm.[Suppl ID], '0', ' ')), ' ', '0'),
pm.Country,
pm.PCat,
pm.[Supplier Status PMCT] + pm.[ES (Supplier)],
pm.[Eval Date],
pm.[End Date],
pm.Evaluator,
pm.[SEval (Project)],
pm.[Overdue Date],
pm.[Eval ID],
pm.[ES (Supplier)],
bb.BranchOffice,
bb.Zone,
pm.[Project ID],
pm.Score,
pm.NCC,
pm.[NCC Amount],
pm.PM,
pm.[Suppl Name],
pm.Comment,
pm.[Comment Problem],
pm.Problem,
pm.Purchasing,
pm.Logistics,
pm.[Quality and EHS],
pm.Technology,
pm.[Devel Status],
pm.[NCC 1],
pm.[NCC Recovered],
pm.Name,
pm.[Root Cause],
pm.[Comment Action],
pm.Claim
HAVING
pm.[Eval Date] >= DATEADD(MONTH, -14, GETDATE())
OR
pm.[Eval Date] IS NULL
ORDER BY
pm.[Eval Date] DESC
Here is the original Access query:
SELECT [qry - BT PMCT CA - A - Inactive R].[Supplier number-BS], [qry - BT PMCT CA - A - Inactive R].Period, [qry - BT PMCT CA - A - Inactive R].FY, [qry - BT PMCT CA - A - Inactive R].Division, [qry - BT PMCT CA - A - Inactive R].Country, [qry - BT PMCT CA - A - Inactive R].PCat, [qry - BT PMCT CA - A - Inactive R].[PMCT Validation 1], [qry - BT PMCT CA - A - Inactive R].[Eval Date], [qry - BT PMCT CA - A - Inactive R].[End Date], [qry - BT PMCT CA - A - Inactive R].Evaluator, [qry - BT PMCT CA - A - Inactive R].[PMCT Evaluation Status], [qry - BT PMCT CA - A - Inactive R].[PMCT Star Rating], [qry - BT PMCT CA - A - Inactive R].[Overdue Date], [qry - BT PMCT CA - A - Inactive R].[Eval ID], [qry - BT PMCT CA - A - Inactive R].[ES (Supplier)], [qry - BT PMCT CA - A - Inactive R].[Branch Office], [qry - BT PMCT CA - A - Inactive R].Zone, [qry - BT PMCT CA - A - Inactive R].[Project ID], [qry - BT PMCT CA - A - Inactive R].Score, [qry - BT PMCT CA - A - Inactive R].NCC, [qry - BT PMCT CA - A - Inactive R].[NCC Amount], [qry - BT PMCT CA - A - Inactive R].PM, [qry - BT PMCT CA - A - Inactive R].[Supplier name-BS], [qry - BT PMCT CA - A - Inactive R].Comment, [qry - BT PMCT CA - A - Inactive R].[Comment Problem], [qry - BT PMCT CA - A - Inactive R].Problem, [qry - BT PMCT CA - A - Inactive R].Purchasing, [qry - BT PMCT CA - A - Inactive R].Logistics, [qry - BT PMCT CA - A - Inactive R].[Quality and EHS], [qry - BT PMCT CA - A - Inactive R].Technology, [qry - BT PMCT CA - A - Inactive R].[Devel Status], [qry - BT PMCT CA - A - Inactive R].[Open Supplier NCC], [qry - BT PMCT CA - A - Inactive R].[NCC 1], [qry - BT PMCT CA - A - Inactive R].[NCC Recovered], [qry - BT PMCT CA - A - Inactive R].Name, [qry - BT PMCT CA - A - Inactive R].[Root Cause], [qry - BT PMCT CA - A - Inactive R].[Comment Action], [qry - BT PMCT CA - A - Inactive R].Claim
FROM [qry - BT PMCT CA - A - Inactive R]
GROUP BY [qry - BT PMCT CA - A - Inactive R].[Supplier number-BS], [qry - BT PMCT CA - A - Inactive R].Period, [qry - BT PMCT CA - A - Inactive R].FY, [qry - BT PMCT CA - A - Inactive R].Division, [qry - BT PMCT CA - A - Inactive R].Country, [qry - BT PMCT CA - A - Inactive R].PCat, [qry - BT PMCT CA - A - Inactive R].[PMCT Validation 1], [qry - BT PMCT CA - A - Inactive R].[Eval Date], [qry - BT PMCT CA - A - Inactive R].[End Date], [qry - BT PMCT CA - A - Inactive R].Evaluator, [qry - BT PMCT CA - A - Inactive R].[PMCT Evaluation Status], [qry - BT PMCT CA - A - Inactive R].[PMCT Star Rating], [qry - BT PMCT CA - A - Inactive R].[Overdue Date], [qry - BT PMCT CA - A - Inactive R].[Eval ID], [qry - BT PMCT CA - A - Inactive R].[ES (Supplier)], [qry - BT PMCT CA - A - Inactive R].[Branch Office], [qry - BT PMCT CA - A - Inactive R].Zone, [qry - BT PMCT CA - A - Inactive R].[Project ID], [qry - BT PMCT CA - A - Inactive R].Score, [qry - BT PMCT CA - A - Inactive R].NCC, [qry - BT PMCT CA - A - Inactive R].[NCC Amount], [qry - BT PMCT CA - A - Inactive R].PM, [qry - BT PMCT CA - A - Inactive R].[Supplier name-BS], [qry - BT PMCT CA - A - Inactive R].Comment, [qry - BT PMCT CA - A - Inactive R].[Comment Problem], [qry - BT PMCT CA - A - Inactive R].Problem, [qry - BT PMCT CA - A - Inactive R].Purchasing, [qry - BT PMCT CA - A - Inactive R].Logistics, [qry - BT PMCT CA - A - Inactive R].[Quality and EHS], [qry - BT PMCT CA - A - Inactive R].Technology, [qry - BT PMCT CA - A - Inactive R].[Devel Status], [qry - BT PMCT CA - A - Inactive R].[Open Supplier NCC], [qry - BT PMCT CA - A - Inactive R].[NCC 1], [qry - BT PMCT CA - A - Inactive R].[NCC Recovered], [qry - BT PMCT CA - A - Inactive R].Name, [qry - BT PMCT CA - A - Inactive R].[Root Cause], [qry - BT PMCT CA - A - Inactive R].[Comment Action], [qry - BT PMCT CA - A - Inactive R].Claim
HAVING ((([qry - BT PMCT CA - A - Inactive R].[Eval Date])>=DateAdd("m",-1,DateAdd("m",-12,Month(Now()) & "/" & [Forms]![Period Form]![txtFiscalYear])) And ([qry - BT PMCT CA - A - Inactive R].[Eval Date])<DateAdd("m",-1,DateAdd("m",-12,Month(Now()) & "/" & [Forms]![Period Form]![txtFiscalYear]))+365)) OR ((([qry - BT PMCT CA - A - Inactive R].[Eval Date]) Is Null));
Related
This is a real working formula in my google sheet. I have 5 cells in which the user chooses values from data validated drop down lists. This formula then chooses the sheet to filter then filters on those values. Obviously, my issue is speed. So I'm hoping if I create a custom function or functions I will improve performance of my calculations. My question is, what would be the best way to proceed. create one function or should I break it down into the various functions and build a formula from multiple custom functions. Will I see an improvement? I'm also considering not setting the formula until the user clicks an image button (to avoid the formula constantly recalculating while the user is making their picks.
=if(E4= "View All Contacts", filter('View All Contacts'!$A$1:$L$3999,if(I8<>"",'View All Contacts'!A:A =I8,'View All Contacts'!A:A <>""),if(E7<>"",'View All Contacts'!M:M =E7,'View All Contacts'!A:A <>""),if(E9<>"",'View All Contacts'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View All Contacts'!N:N = (year(NOW()) - 1 )) + ('View All Contacts'!N:N = (year(Now()) - 5 ) )+ ('View All Contacts'!N:N = (year(Now()) - 10 ) )+ ('View All Contacts'!N:N = (year(Now()) - 15 ) )+ ('View All Contacts'!N:N = (year(Now()) - 20 )) + ('View All Contacts'!N:N = (year(Now()) - 25 ) )+ ('View All Contacts'!N:N = (year(Now()) - 30 ) )+ ('View All Contacts'!N:N = (year(Now()) - 40 ) )+ ('View All Contacts'!N:N = (year(Now()) - 50 )) + ('View All Contacts'!N:N = (year(Now()) - 60 ) )+ ('View All Contacts'!N:N = (year(Now()) - 70 )) + ('View All Contacts'!N:N = (year(Now()) - 75 ) )+ ('View All Contacts'!N:N = (year(Now()) - 80 ) )+ ('View All Contacts'!N:N = (year(Now()) - 90 )) + ('View All Contacts'!N:N = (year(Now()) - 100 )) + ('View All Contacts'!N:N = (year(Now()) - 125 ) )+ ('View All Contacts'!N:N = (year(Now()) - 150 ) )+ ('View All Contacts'!N:N = (year(Now()) - 175 )) + ('View All Contacts'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View All Contacts'!N:N < (year(Now())) - 100) * ('View All Contacts'!N:N <>""), If(E8 >0, 'View All Contacts'!N:N = (year(NOW()) - E8 ),'View All Contacts'!A:A <>""))))),if(E4 = "View Active Contacts",filter('View Active Contacts'!$A$1:$L$3999,if(I8<>"",'View Active Contacts'!A:A =I8,'View Active Contacts'!A:A <>""),if(E7<>"",'View Active Contacts'!M:M =E7,'View Active Contacts'!A:A <>""),if(E9<>"",'View Active Contacts'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View Active Contacts'!N:N = (year(NOW()) - 1 )) + ('View Active Contacts'!N:N = (year(Now()) - 5 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 10 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 15 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 20 )) + ('View Active Contacts'!N:N = (year(Now()) - 25 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 30 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 40 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 50 )) + ('View Active Contacts'!N:N = (year(Now()) - 60 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 70 )) + ('View Active Contacts'!N:N = (year(Now()) - 75 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 80 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 90 )) + ('View Active Contacts'!N:N = (year(Now()) - 100 )) + ('View Active Contacts'!N:N = (year(Now()) - 125 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 150 ) )+ ('View Active Contacts'!N:N = (year(Now()) - 175 )) + ('View Active Contacts'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View Active Contacts'!N:N < (year(Now())) - 100) * ('View Active Contacts'!N:N <>""), If(E8 >0, 'View Active Contacts'!N:N = (year(NOW()) - E8 ),'View Active Contacts'!A:A <>""))))),if(E4 = "View Contacts from Companies Pending Current Payments",filter('View Contacts from Companies Pending Current Payments'!$A$1:$L$3999,if(I8<>"",'View Contacts from Companies Pending Current Payments'!A:A =I8,'View Contacts from Companies Pending Current Payments'!A:A <>""),if(E7<>"",'View Contacts from Companies Pending Current Payments'!M:M =E7,'View Contacts from Companies Pending Current Payments'!A:A <>""),if(E9<>"",'View Contacts from Companies Pending Current Payments'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View Contacts from Companies Pending Current Payments'!N:N = (year(NOW()) - 1 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 5 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 10 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 15 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 20 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 25 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 30 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 40 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 50 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 60 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 70 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 75 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 80 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 90 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 100 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 125 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 150 ) )+ ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 175 )) + ('View Contacts from Companies Pending Current Payments'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View Contacts from Companies Pending Current Payments'!N:N < (year(Now())) - 100) * ('View Contacts from Companies Pending Current Payments'!N:N <>""), If(E8 >0, 'View Contacts from Companies Pending Current Payments'!N:N = (year(NOW()) - E8 ),'View Contacts from Companies Pending Current Payments'!A:A <>""))))),if(E4 = "View Inactive Companies Contacts",filter('View Inactive Companies Contacts'!$A$1:$L$3999,if(I8<>"",'View Inactive Companies Contacts'!A:A =I8,'View Inactive Companies Contacts'!A:A <>""),if(E7<>"",'View Inactive Companies Contacts'!M:M =E7,'View Inactive Companies Contacts'!A:A <>""),if(E9<>"",'View Inactive Companies Contacts'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View Inactive Companies Contacts'!N:N = (year(NOW()) - 1 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 5 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 10 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 15 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 20 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 25 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 30 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 40 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 50 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 60 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 70 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 75 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 80 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 90 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 100 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 125 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 150 ) )+ ('View Inactive Companies Contacts'!N:N = (year(Now()) - 175 )) + ('View Inactive Companies Contacts'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View Inactive Companies Contacts'!N:N < (year(Now())) - 100) * ('View Inactive Companies Contacts'!N:N <>""), If(E8 >0, 'View Inactive Companies Contacts'!N:N = (year(NOW()) - E8 ),'View Inactive Companies Contacts'!A:A <>""))))),if(E4 = "View Contacts from Companies with Expired Memberships",filter('View Contacts from Companies with Expired Memberships'!$A$1:$L$3999,if(I8<>"",'View Contacts from Companies with Expired Memberships'!A:A =I8,'View Contacts from Companies with Expired Memberships'!A:A <>""),if(E7<>"",'View Contacts from Companies with Expired Memberships'!M:M =E7,'View Contacts from Companies with Expired Memberships'!A:A <>""),if(E9<>"",'View Contacts from Companies with Expired Memberships'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View Contacts from Companies with Expired Memberships'!N:N = (year(NOW()) - 1 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 5 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 10 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 15 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 20 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 25 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 30 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 40 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 50 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 60 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 70 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 75 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 80 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 90 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 100 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 125 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 150 ) )+ ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 175 )) + ('View Contacts from Companies with Expired Memberships'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View Contacts from Companies with Expired Memberships'!N:N < (year(Now())) - 100) * ('View Contacts from Companies with Expired Memberships'!N:N <>""), If(E8 >0, 'View Contacts from Companies with Expired Memberships'!N:N = (year(NOW()) - E8 ),'View Contacts from Companies with Expired Memberships'!A:A <>""))))),if(E4 = "View Contacts from Potential Companies",filter('View Contacts from Potential Companies'!$A$1:$L$3999,if(I8<>"",'View Contacts from Potential Companies'!A:A =I8,'View Contacts from Potential Companies'!A:A <>""),if(E7<>"",'View Contacts from Potential Companies'!M:M =E7,'View Contacts from Potential Companies'!A:A <>""),if(E9<>"",'View Contacts from Potential Companies'!O:O =E9,if(E8 = "All Mile Stone Anniversaries",('View Contacts from Potential Companies'!N:N = (year(NOW()) - 1 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 5 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 10 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 15 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 20 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 25 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 30 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 40 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 50 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 60 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 70 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 75 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 80 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 90 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 100 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 125 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 150 ) )+ ('View Contacts from Potential Companies'!N:N = (year(Now()) - 175 )) + ('View Contacts from Potential Companies'!N:N = (year(Now()) - 200 )),If(E8 = ">100", ('View Contacts from Potential Companies'!N:N < (year(Now())) - 100) * ('View Contacts from Potential Companies'!N:N <>""), If(E8 >0, 'View Contacts from Potential Companies'!N:N = (year(NOW()) - E8 ),'View Contacts from Potential Companies'!A:A <>""))))),""))))))
It's better if you'll break it down into the various functions and build a formula from multiple custom functions. As you've said, the performance will be slow if you're working on a sheet with lots of filter formulas.
Here are some references which may help:
https://www.quora.com/How-do-I-set-up-a-function-in-a-Google-Sheets-cell-to-take-the-input-value-as-variable
Using a Custom Function in a Google Spreadsheet?
https://productforums.google.com/forum/#!topic/docs/0uUV9PKSVpU
Yikes! My eyes glaze just looking at that formula. I really can't figure out what you are trying to do. In general a spreadsheet formula more than one line long is a write-only language.
Break it down into chunks. You can create multiple sheets with various stages of calculation. Generally there isn't a performance penalty for splitting this up.
Avoid constructs of the form
if(E4= "View All Contacts"...
Instead use
if (E4=C2, filter(FilterRange,C2)
or if your tag isn't the same as what you are filtering...
if(E4= C2, filter(vlookup(FilterRange,C2,2)...
Filter can take multiple ranges that have to evaluate to true or false.
This allows you to set up the matching conditions outside of the formula.
The pink box uses a regexmatch. This is very powerful, but can be slow on big arrays.
The green box uses a simple match, faster, but limited to only one item
The orange box shows the results: Either Critter starts with a or A OR class is fish.
By using Named ranges throughout, I have a MUCH more maintainable spreadsheet. Named ranges do the Right Thing most of the time when you expand them. If you used a named range in multiple places, you only have to edit it once.
It's good practice to put auxiliary tables on a separate tab, at least out of sight of users (including yourself.
You can do more of the logic in the auxiliary sheet. E.g. Add a 3rd range after fish with a an arrayformula (OR(FTest_CritFilt,FTest_ClassFilt))
When you are creating this sheet, you can have it open in two browser windows with the view on different tabs.
I am trying to update all customers payment terms based on the oldest invoice. So far I have the following code:
UPDATE [CUSTOMERS - Main]
SET Payterms = 0
FROM (SELECT Max(INVOICES.InvoiceDate) AS LastInvoice,
Datediff(day, Max(INVOICES.InvoiceDate), Getdate()) AS age,
INVOICES.CompanyName,
[CUSTOMERS - Main].PayTerms,
[CUSTOMERS - Main].CreditLimit,
[CUSTOMERS - Main].CompanyRegNo
FROM INVOICES
INNER JOIN [CUSTOMERS - Main]
ON INVOICES.CompanyName = [CUSTOMERS - Main].CompanyName
GROUP BY INVOICES.CompanyName,[CUSTOMERS - Main].PayTerms,[CUSTOMERS - Main].CreditLimit,[CUSTOMERS - Main].CompanyRegNo
HAVING (Datediff(day, Max(INVOICES.InvoiceDate), Getdate()) > 365)
AND ([CUSTOMERS - Main].PayTerms > 0
OR [CUSTOMERS - Main].CreditLimit > 0))
But it's not working. How do I update a query that has an aggregate function?
This seems to be a much tidier approach, though I may be off by a day from your actual intention, e.g. today is December 10, do you want to exclude customers with any invoice newer than December 10 of last year, or December 11? This excludes customers with an invoice newer than December 10.
DECLARE #cutoff DATE = DATEADD(DAY, -365, GETDATE());
UPDATE c SET Payterms = 0
FROM dbo.[CUSTOMERS - Main] AS c
WHERE (c.PayTerms > 0 OR c.CreditLimit > 0)
AND NOT EXISTS
(
SELECT 1 FROM dbo.INVOICES AS i
WHERE i.CompanyName = c.CompanyName
AND InvoiceDate >= #cutoff
);
I have been trying for the best part of the day to remove the intersect since it is not supported by mysql. If anyone can provide some pointers it would be really helpful.
SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM user U, user_utilisation UU
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 6
GROUP BY U.id_user
HAVING age >= 1 AND age <= 100
ORDER BY nom, prenom
INTERSECT
SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM user U, user_utilisation UU
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 7
GROUP BY U.id_user
HAVING age >= 1 AND age <= 100
ORDER BY nom, prenom
I tried with JOIN(s) but here's what I have right now:
SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(naissance, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(naissance, '00-%m-%d')) AS age
FROM user U, user_utilisation UU
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M'
AND UU.id_user IN (select id_user from user_utilisation where id_mailing = 6 OR id_mailing = 7)
HAVING age >= 1 AND age <= 100
ORDER BY nom, prenom
but by removing the GROUP BY I see that the query selected 2 records where id_mailing = 1, while the GROUP BY is hiding the wrong record. I'm pretty sure that this could cause problems...
user_utilisation only has three fields id_user, id_mailing, and date.
Interpreting your queries, it seems to me:
You want to get all users who participate in mailing_id 6 and 7 (that's why you are doing the INTERSECT, is that right?).
You want to restrict those users by criteria and perform an age calculation.
If my interpretation of your intent is correct (not at all sure that is the case!), you don't need INTERSECT at all, you should be able to simply select the users you want with the criteria you want, and restrict participation in both mailing 6 and 7 via JOIN:
SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM user U
INNER JOIN user_utilisation UU on U.id_user = UU.id_user and UU.mailing_id = 6
INNER JOIN user_utilisation UU2 on U.id_user = UU2.id_user and UU2.mailing_id = 7
WHERE cp >= 1 AND cp <= 3000 AND sexe = 'M'
HAVING age >= 1 AND age <= 100
ORDER BY nom, prenom
You could try something like the following:
SELECT *
FROM
(SELECT *
, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM user U
INNER JOIN user_utilisation UU
ON U.id_user = UU.id_user
WHERE cp >= 1 AND cp <= 3000
AND sexe = 'M'
AND UU.id_mailing = 6
GROUP BY U.id_user
HAVING age >= 1 AND age <= 100) QUERY1
WHERE EXISTS(SELECT *
, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM user U
INNER JOIN user_utilisation UU
ON U.id_user = UU.id_user
WHERE cp >= 1 AND cp <= 3000
AND sexe = 'M'
AND UU.id_mailing = 7
AND U.id_user = QUERY1.id_user
GROUP BY U.id_user
)
ORDER BY nom, prenom
The trick in the query above is that the WHERE EXISTS( ... ) clause acts as a filter, similar to the INTERSECT you were using before. The idea is that you will want to only select those records from the query QUERY1 that meet the criteria that there is at least one record in the query in the EXITS clause which is conditioned on the id_user being the same as the id_user from the QUERY1 query.. I hope this makes some sense..
I could probably tune it a little bit for you if you would provide the structure of the User table. And by the way, using those blanket SELECT * statements is not a good idea..
I think you can simplify the query. It is has several curiosities. First, the query doesn't use proper join syntax. Second, the query is using the having clause just to filter on an alias from the select. I recommend a subquery in that case.
It looks like you are trying to get users who are in both "groups" as defined by two very similar queries (only the where clause is different). The following may be what you are looking for:
select t.*
from (SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age,
(case when cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 6 then 'FirstGroup'
when cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 7 then 'SecondGroup'
end) as thegroup
FROM user U join user_utilisation UU
on U.id_user = UU.id_user
) t
where thegroup is not null and age between 1 and 100
GROUP BY U.id_user
having max(thegroup) <> min(thegroup)
ORDER BY nom, prenom
The having clause is a short-hand way of saying that the user is in both groups.
I have a user table with the user's birthday (YYYY-MM-DD) as well as age. I want to run a script to calculate and update the age column nightly via cron.
This SQL works well for selecting and calculating the age:
SELECT
DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`
But is it possible to update the age column with a single statement? Tried the following, but all I managed to do was populate the age column with all 0s! Do I need to use some sort of MySQL loop?
UPDATE
`jos_jcourse_students`
SET
age = "SELECT DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`"
UPDATE `jos_jcourse_students`
SET age = DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birthday)), '%Y')+0
OR according to your logic it will be
UPDATE `jos_jcourse_students`
SET age =((DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`birthday`, '%Y')) -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')))
UPDATE
`jos_jcourse_students`
SET
age = (SELECT DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`)
One way you can achieve the above result by using the self join technique. i.e join to the same table using its unique id (primary key example studentId)
UPDATE jos_jcourse_students a,
( SELECT studentId, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`birthday`, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM `jos_jcourse_students`) b
SET a.age = b.age
WHERE a.studentId = b.studentId
Note: studentId is primary key in jos_jcourse_students
What I am trying to do is have a field called 'age' autopopulate from a persons date of birth when a row is added - the trick is the persons date of birth resides in anouther field.
My two tables are:
student
student_id (PK), first_name, last_name, date_of_birth
fitness_report
report_id (PK), test_date, test_period, age_tested, student_id (FK)
ideally the age_tested will be caluclated from the test_period however happy to use ()NOW as that'll be within reasonable limits.
Obviously what i need to do here is create a trigger - but not sure on the SELECT statement to get the age to populate. Help is much appreciated.
As rwilliams said, it is not advisable to store the age_tested as it is redundant but if it is what you want to do you can wrap a simple trigger around Mosty's solution -
CREATE TRIGGER fitness_report_insert BEFORE INSERT ON `fitness_report`
FOR EACH ROW
BEGIN
SET NEW.age_tested = (SELECT DATE_FORMAT(NEW.test_period, '%Y') - DATE_FORMAT(student.date_of_birth, '%Y') - (DATE_FORMAT(NEW.test_period, '00-%m-%d') < DATE_FORMAT(student.date_of_birth, '00-%m-%d')) FROM student WHERE student.student_id = NEW.student_id);
END
This assumes that test_period is a date as previously mentioned by Mosty. I have not tried this as I do not have access to a server right now so it may need a little tweaking.
UPDATE: You could try the following as a starting point for your stats -
SELECT
DATE_FORMAT(test_period, '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(test_period, '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS age,
s.gender,
AVG(r.score) AS score
FROM student s
INNER JOIN fitness_report r
ON s.student_id = r.student_id
GROUP BY age, s.gender
This is how to get current age:
select s.name, s.date_of_birth,
date_format(now(), '%Y') - date_format(date_of_birth, '%Y') -
(date_format(now(), '00-%m-%d') < date_format(date_of_birth, '00-%m-%d'))
as age
from s
Example
This is how to get age up to the test_period (shouldn't it be test_date?):
select s.name, s.date_of_birth, r.test_period,
date_format(test_period, '%Y') - date_format(date_of_birth, '%Y') -
(date_format(test_period, '00-%m-%d') < date_format(date_of_birth, '00-%m-%d'))
as age
from r
join s on s.id_student = r.student_id
Example