I'm working in Access 2010. I have the following query (which is named bird_year_species):
SELECT sub.Species, Min(sub.obs_year) AS First_sighting_year
FROM (SELECT DISTINCT [Genus_BiLE] & " " & [Species_BiLE] AS Species, [Year_BiLE] AS obs_year
FROM BiLE_Bound
UNION ALL
SELECT DISTINCT [Genus_BiMN] & " " & [Species_BiMN] AS Species, [Year_BiMN] AS obs_year
FROM BiMN_Bound
UNION ALL
SELECT DISTINCT [Genus_BiPC] & " " & [Species_BiPC] AS Species, [Year_BiPC] AS obs_year
FROM BiPC_Bound
UNION ALL
SELECT Distinct [Genus_BiOP] & " " & [Species_BiOP] AS Species, [Year_BiOP] AS obs_year
FROM BiOP_Rec
) AS sub
GROUP BY sub.Species;
When I open it I get a popup asking for a parameter value for Query1.obs_year. If I just fill in anything and hit okay the table pops up and it works. I've no idea why this is happening, and the query is not named Query1.
I tried copying the code into a new query. I tried compacting an repairing. I tried saving the database under another name. Non of which worked.
Eventually I opened the query, switched out of SQL view and into design view, back to SQL view and voila, that appeared to do it. So strange.
When this happens, check your properties, specifically look for references to Queryx in the filter and order by fields.
I had the same problem, and OP solution didn't work for me because the it was caused by something else.
In case someone else is in my condition and stumbles upon this question I'm gonna post cause and solution.
It may be something really basic as I'm a beginner at using Access, but maybe it may help someone out there.
I had a query with both a GROUP BY and some calculated column.
something like
Select A, B, (A*B) AS C, (A+B) AS D
FROM table
GROUP BY A, B
I then added from the design view another calculated field based on C and D and i started getting asked for C and D when running the query.
Looking at the SQL, the design resulted in a wrong query:
Select A, B, (A*B) AS C, (A+B) AS D, (D*C) as E
FROM table
GROUP BY A, B, [D]*[C]
Notice how the expression was added to the group by?
That's why it was asking for the value when running the query.
SOLUTION
Remove the unnecessary grouping from the sql
or
From the design view change the Total value of the column from Group By to Expression
Related
I am trying to run what it started as a simple task but it turned out to be more complicated.
I must run a local sum of a column over different elements of another column with a query function.
The issue arises because the query performs an unwanted sorting of the grouped column (it is in the format of working weeks - strings) and I cannot get it to unsort or re-sort in the original format.
Initial query is:
=query(A1:B350,"select A, sum(B) group by A")
See the example:
click here to see example
Subsequently I tried with:
=query(A1:B350,"select A, sum(B) where A matches '"&join("|", query(G2:G, "select G where G is not null"))& "' group by A")
like so:
click here to see example
but the unwanted sorting remains.
Any idea on how to force the initial sorting or preventing it from changing?
Thank you in advance
To sort correctly, you need to align single digits. You can do this either in the source data or using a formula:
=QUERY({INDEX(REGEXREPLACE(A:A,"-(\d)$","-0$1")),B:B},"SELECT Col1, SUM(Col2) GROUP BY Col1")
try:
=INDEX(IFNA(VLOOKUP(G2:G,
QUERY(A1:B350, "select A,sum(B) group by A label sum(B)''"), {1, 2}, 0)))
I have this ms access query:
SELECT t1.sb, suchbegriff2, menge
FROM (SELECT artnr & '/' & [lfdnr-kal] AS sb, left(suchbegriff,7) &
val(right(suchbegriff,4)) AS suchbegriff2
FROM kvks
WHERE suchbegriff like '*/*') AS t1
INNER JOIN (SELECT artnr & '/' & [lfdnr-kal] AS sb,
[artnr-hz] & '/' & val(lfdnr) AS hz, menge
FROM konf
WHERE [artnr-hz]<>'') AS t2
ON (t1.sb=t2.sb) AND (t1.suchbegriff2=t2.hz);
It runs really very slow (over 30 sec.). I figured out, it is because the inner join part. If I leave this, the speed is correct.
Maybe it is because of the fact slow, that the joined fields are calculated expressions?
EDIT:
I modified the query based on the answer of Smandoli:
SELECT kvks.artnr & '/' & kvks.[lfdnr-kal] AS sb,
left(suchbegriff,7) & val(right(suchbegriff,4)) AS suchbegriff2,
konf.menge
FROM kvks, konf
WHERE kvks.suchbegriff like '*/*'
and konf.[artnr-hz]<>''
and kvks.artnr=konf.artnr
and kvks.[lfdnr-kal]=konf.[lfdnr-kal]
and left(suchbegriff,7) & val(right(suchbegriff,4))=[artnr-hz] & '/' & val(lfdnr)
It runs now correct.
Thanks for your contribution.
You do have a complicated mess with those calculated fields. Why not join more directly? This query below leaves one '/' unaccounted for, but should tell you what I'm thinking of.
SELECT
t1.sb,
left(st1.uchbegriff,7) & val(right(t1.suchbegriff,4)) AS suchbegriff2,
t1.menge
FROM kvks AS t1
INNER JOIN konf AS t2
WHERE (t1.suchbegriff like '*/*')
AND (t2.artnr-hz<>'')
AND (t1.artnr=t2.artnr)
AND (t1.lfdnr-kal=t2.lfdnr-kal)
AND (left(t1.suchbegriff,7)=t1.[artnr-hz])
AND (val(right(t1.suchbegriff,4))=val(t2.hz));
For the inner join, you can try to use a saved query (or temp table) instead of writing the query at run time.
So, I would first try to abstract this query
SELECT artnr & '/' & [lfdnr-kal] AS sb,
[artnr-hz] & '/' & val(lfdnr) AS hz, menge
FROM konf
WHERE [artnr-
hz]<>'') AS t2
ON (t1.sb=t2.sb) AND (t1.suchbegriff2=t2.hz)
Second of all, if possible, I would abstract some of the functions in the queries. You could do this with VBA, or manipulating the data outside of the queries.
Third, you could always create a field on your table that combines the two fields together that you need.
E.x: Make a new column in your konf table that stores the value of artnr & '/' & [lfdnr-kal]
What you need to do is limit the functions/calculations/coalescing of fields at run time. That's a lot for a query to do, and if it's running slow I would see a direction correlation either between that, or something incorrect with your indexes/joins.
If you've identified this as a join issue, you can use VBA to spin up a temp table with your queries, and use those as the record source instead of the SQL.
Also, if you don't utilize a temp table, at least save the queries. This allows Access to have a plan for running the queries, whereas your query is 100% run-time dependent.
Your query runs slow because of "Nesting" and then "Joining". You can try creating the temp tables and used that table in query. Creating temp table is good practice rather than making the query complex.
99999!!! I think you have just to implement some index
(t1.sb=t2.sb) AND (t1.suchbegriff2=t2.hz);
these ones are very suspicious. Are the 4 indexed?
I use this forum all the time for VBA help but this is the first time I have to post something myself.
I am trying to make a report that provides a summary of various alarms stored in Access. I want to provide a simple Count of each alarm, each day. I have used some SQL queries but not really any Access. I took the fact that Access can do Pivot tables from Access itself. If there is a better way, please let me know.
Set CommandQuery.activeConnection = conn
commandQuery.CommandText = _
"TRANSFORM Count(FixAlarms.[Alm_NativeTimeLast]) AS CountOfAlm_NativeTimeLast " & _
"SELECT FixAlarms.Alm_Tagname, FixAlarms.Alm_Desc " & _
"FROM FixAlarms " & _
"WHERE ((FixAlarms.Alm_Tagname) <> """")) AND FixAlarms.Alm_NativeTimeIn > CellTime " & _
"GROUP BY FixAlarms.[Alm_Tagname], FixAlarms.Alm_Descr " & _
"PIVOT Format([Alm_NativeTimeIn],""Short Date"")"
rec.Open commandQuery
This is the code I am using. I had to retype it, so please forgive any typo. It does most of what I want but it does not give me any indication of what day each column is. I need a header on each column in case there were no alarms one day. I think the answer lies within the IN part of the PIVOT but I can't get it to work without syntax errors. I thought all I had to do was add on
PIVOT Format([Alm_NativeTimeIn],""Short Date"") IN 01/20/15"
Please help if you can.
Thanks.
In order to get the records for all day, even those where there were no activity you need to create these days. The simplest way to do so in access is to use a set of UNION statements to create a fake table for the days similar to this:
SELECT #2015-01-20# as dt FROM dual
UNION ALL
SELECT #2015-01-21# as dt FROM dual
UNION ALL
SELECT #2015-01-22# as dt FROM dual
If you try the above query in Access it will not work, as there is no table called dual. You will have to create it. Check this SO question.
After you created the above query you can LEFT JOIN it with the source table.
TRANSFORM Count(FixAlarms.[Alm_NativeTimeLast]) AS CountOfAlm_NativeTimeLast
SELECT FixAlarms.Alm_Tagname, FixAlarms.Alm_Desc
FROM
(SELECT #2015-01-20# as dt FROM dual
UNION ALL
SELECT #2015-01-21# as dt FROM dual
UNION ALL
SELECT #2015-01-22# as dt FROM dual) as dates LEFT JOIN
FixAlarms ON DateValue(FixAlarms.[Alm_NativeTimeIn]) = dates.dt
WHERE ((FixAlarms.Alm_Tagname) <> """")) AND FixAlarms.Alm_NativeTimeIn > CellTime
GROUP BY FixAlarms.[Alm_Tagname], FixAlarms.Alm_Descr
PIVOT Format(dates.dt, 'Short Date')
EDIT: I must add that this is not the only way of achieving it. Another way is to use a Numbers table. Create a table called Numbers with a single numeric column n and fill it with numbers 0 to 100 (depends on the maximum number of days you wish to include into your query). Then your query for the dates will be:
SELECT DateAdd('d', n, #2015-01-20#) as dt FROM numbers where n < 30;
And the resulting query will be:
TRANSFORM Count(FixAlarms.[Alm_NativeTimeLast]) AS CountOfAlm_NativeTimeLast
SELECT FixAlarms.Alm_Tagname, FixAlarms.Alm_Desc
FROM
(SELECT DateAdd('d', n, #2015-01-20#) as dt FROM numbers where n < 30) as dates LEFT JOIN
FixAlarms ON DateValue(FixAlarms.[Alm_NativeTimeIn]) = dates.dt
WHERE ((FixAlarms.Alm_Tagname) <> """")) AND FixAlarms.Alm_NativeTimeIn > CellTime
GROUP BY FixAlarms.[Alm_Tagname], FixAlarms.Alm_Descr
PIVOT Format(dates.dt, 'Short Date')
When using PIVOT columnName IN (ValueList) ValueList is
In parentheses
In quotes
Comma separated
So you're
PIVOT Format([Alm_NativeTimeIn],""Short Date"") IN 01/20/15"
Needs to become
PIVOT Format([Alm_NativeTimeIn],""Short Date"") IN (""01/20/15"")
With that said, this will not filter your records using PIVOTS in IN statement. You need to use the WHERE clause still.
If the end goal is to represent your data left to right then this will work. It will be a lot of extra work to make this work as a report though because your controls will not be bound to predictable columns. The Column names will change for different parameters.
You could leave this as a traditional query (not pivoted) and have a much easier time reporting it. If you are showing users the grid directly or exporting to Excel then this is not a problem.
So, I just wanted to add a header to my pivot table that would tell me what date the particular column was for.
The part of the code that I did not show was that I was using a rec.getrows to move all of my data into a simpler array variable. While this had all the data from Access, it did not have any headers to inform me what was a tagname, what was a description, and what was which date.
I found that in the recordset itself under fields.item(n) there was a Name attribute. This name told me where the column data came from or the date of the data. Using this and a simple day(date) function, I was able to make my monthly report summarizing all of the alarms.
Thanks for your help guys, but I either was not clear in my description of the problem or it was being over thought.
I am having an issue with a query which returns results that are very far from reality (not only does it not make sense at all but I can also calculate the correct answer using filters).
I am building a KPI db for work and this query returns KPIs by employee by period. I have a very similar query from which this one is derived which returns KPIs by sector by period which gives the exact results I have calculated using a spreadsheet. I really have no idea what happens here. Basically, I want to sum a few measures that are in the maintenances table like temps_requete_min, temps_analyse_min, temps_maj_min and temps_rap_min and then create a subtotal AND present these measures as hours (measures are presented in minutes, thus the divide by 60).
SELECT
[anal].[prenom] & " " & [anal].[nom] AS Analyste,
maint.periode, maint.annee,
Round(Sum(maint.temps_requete_min)/60,2) AS REQ,
Round(Sum(maint.temps_analyse_min)/60,2) AS ANA,
Round(Sum(maint.temps_maj_min)/60,2) AS MAJ,
Round(Sum(maint.temps_rap_min)/60,2) AS RAP,
Round((Sum(maint.temps_requete_min)+Sum(maint.temps_analyse_min)+Sum(maint.temps_maj_min)+Sum(maint.temps_rap_min))/60,2) AS STOTAL,
Count(maint.periode) AS Nombre,
a.description
FROM
rapports AS rap,
analyste AS anal,
maintenances AS maint,
per_annuelle,
annees AS a
WHERE
(((rap.id_anal_maint)=anal.id_analyste) And
((maint.id_fichier)=rap.id_rapport) And
((maint.maint_effectuee)=True) And
((maint.annee)=per_annuelle.annee) And
((per_annuelle.annee)=a.annees))
GROUP BY
[anal].[prenom] & " " & [anal].[nom],
maint.periode,
maint.annee,
a.description,
anal.id_analyste
ORDER BY
maint.annee, maint.periode;
All measures are many orders of magnitude higher than what they should be. I suspect that my Count() is wrong, but I can't see what would be wrong with the sums :|
Edit: Finally I have come up with this query which shows the same measures I have calculated using Excel from the advice given in the comments and the answer provided. Many thanks to everyone. What I would like to know however, is why it makes a difference to use explicit joins rather than implicit joins (WHERE clause on PKs).
SELECT
maintenances.periode,
[analyste].[prenom] & " " & analyste.nom,
Round(Sum(maintenances.temps_requete_min)/60,2) AS REQ,
Round(Sum(maintenances.temps_analyse_min)/60,2) AS ANA,
Round(Sum(maintenances.temps_maj_min)/60,2) AS MAJ,
Round(Sum(maintenances.temps_rap_min)/60,2) AS RAP,
Round((Sum(maintenances.temps_requete_min)+Sum(maintenances.temps_analyse_min)+Sum(maintenances.temps_maj_min)+Sum(maintenances.temps_rap_min))/60,2) AS STOTAL,
Count(maintenances.periode) AS Nombre
FROM
(maintenances INNER JOIN rapports ON maintenances.id_fichier = rapports.id_rapport)
INNER JOIN analyste ON rapports.id_anal_maint = analyste.id_analyste
GROUP BY analyste.prenom, maintenances.periode
In this case, the problem is typically that your joins are bringing together multiple dimensions. You end up doing a cross product across two or more categories.
The fix is to do the summaries independently along each dimension. That means that the "from" clause contains subqueries with group bys, and these are then joined together. The group by would disappear from the outer query.
This would suggest having a subquery such as:
from (select maint.periode, maint.annee,
Round(Sum(maint.temps_requete_min)/60,2) AS REQ,
Round(Sum(maint.temps_analyse_min)/60,2) AS ANA,
Round(Sum(maint.temps_maj_min)/60,2) AS MAJ,
Round(Sum(maint.temps_rap_min)/60,2) AS RAP,
Round((Sum(maint.temps_requete_min)+Sum(maint.temps_analyse_min) +Sum(maint.temps_maj_min)+Sum(maint.temps_rap_min))/60,2) AS STOTAL,
Count(maint.periode) AS Nombre,
from maintenances maint
group by maint.periode, maint.annee
) m
I say "such as" because without a layout of the tables, it is difficult to see exactly where the problem is and what the exact solution is.
Being an amateur in Access and VBA, I've hit a wall with the following...
In MS Access 2007, I have the following query:
SELECT .... WHERE format(NZ(l_f_date),'yyyy-mm-dd')<=**'2012-04-03'**);
I have shortened it a bit of course.
The database has approx 20 queries that need to be run on a daily basis. I have created 4 macros to run groups of queries in the manner that I need them to be run. The problem is that in every one of those queries I first have to change the date (like in the upper query). I am looking for the way to automate it a bit more.
I have an idea to create a Form, place a button for every macro on it and 2 textbox-es to enter the 2 dates I need. Now, I need those dates to appear in the bolded part. As I think about it, I have 2 options:
Create a temporary table in the database to store those two dates and pull those 2 fields in my queries.
Insert the value of the textbox somehow directly into the bolded part of the query.
I think I can manage the first solution, but the second one is making my head hurt.
Can you help?
SQL from comment
select proc_desc,count(s) as broj
into upit3
from ( select distinct a.case_id as s,
a.org_case_id,a.act_date as day,d.prod_id,d.prod_desc,
c.fname,c.dpd,c.due_amount,proc_id,proc_desc
from actions_b as a, cases_old_b as c,processes_b as p,
product_dict_b as d
where a.org_case_id=c.[org_ case_id]
and a.act_date=Forms!Form!Text10 and d.prod_id=c.product
and p.proc_id=c.process and not_lead=1 )
group by proc_desc order by proc_desc;
OK, sample data....
In x.dates, value is exactly like this: 03.04.2012
In a.act_date value is like this: 01.07.2011 13:53:56
so if its not possible with this values as they are, is it possible to use a LIKE statement in the query? Pseudo: WHERE a.act_date LIKE x.date%
If its possible, how to use it? i am a novice in sql and access queries... I google but sometimes, like this time, i get stuck.
Thanks
This structure:
SELECT .... WHERE format(NZ(l_f_date),'yyyy-mm-dd')<='2012-04-03');
Is not a good idea. The general rule is to try and stick to field (column) names on the left side of the equals. So
SELECT .... WHERE l_f_date <=#2012-04-03#
Nulls will not be included and I hope your dates are dates and not strings.
Next add the form:
SELECT .... WHERE l_f_date <= Forms!TheNameOfTheForm!TheNameOfTheTextbox
EDIT re comments
You are using the query design window, yes? Please try this test query:
SELECT a.case_id, a.act_date
FROM actions_b AS a
WHERE a.act_date=Forms!Form!Text10
OK, so i decided to create a simple 2-column table in my database that will be used just for storing yesterdays and todays date... i added 2 text-boxes to a form, 1 button and added the next procedure to the button:
Private Sub Command25_Click()
CurrentDb.Execute "DELETE * FROM Datumi"
Dim tbl As Recordset
Set tbl = CurrentDb.OpenRecordset("Datumi")
tbl.AddNew
tbl!brojka = "1"
tbl!datum = Text8.Value
tbl.Update
tbl.AddNew
tbl!brojka = "2"
tbl!datum = Text10.Value
tbl.Update
End Sub
As you can see, the click on the button will clear the table and store new values into 2 rows... row 1 is yesterday, row 2 is today...
And after that im pulling the values from that table like this:
... where x.brojka=1 and format(a.act_date,'yyyy-mm-dd')=format(x.datum,'yyyy-mm-dd') ...
I'm sure it can be done better but this one works for me...
I Solved this problem with :
[Software: MS Access 2013]
CurrentDb.Execute "INSERT INTO [Inventory Transactions] ([Product ID], [Order ID])" _
& "VALUES ( " & Me.Product_ID & ", " & Me.Order_ID & ")"