MS Access Restart Number Sequence - ms-access

trying to do a sequence count in MS Access where the count sequence resets based on another field, so example below, trying to figure out ColB:
ColA ColB
4566 1
5677 1
5677 2
5677 3
8766 1
8766 2
1223 1
Think it might have something to do with the DCount() function, unsure. Would very much appreciate the help ... Thanks!

Calculating a group sequence number in Access query is fairly common topic. Requires a unique identifier field, autonumber should serve.
Using DCount():
SELECT *, DCount("*", "table", "ColA=" & [ColA] & " AND ID<" & ID) + 1 AS GrpSeq FROM table;
Or with correlated subquery:
SELECT *, (SELECT Count(*) FROM table AS D WHERE D.ColA=table.ColA AND D.ID<table.ID)+1 AS GrpSeq FROM table;
An alternative to calculating in query is to use RunningSum property of textbox on a Report with Sorting & Grouping settings.

Related

Column that assigns 0 or 1 if value is correct or not

I am trying to create a column that assigns 0 or 1 if two pieces of data match. So
TrueLocation PerfectLocation PassOrFail
NY Boston 0
Boston Boston 1
My go ahead was not great...
SELECT *, COUNT (TrueLocation) / COUNT(PerfectLocation) as PassOrFail
FROM Table1;
This doesn't work, and I see why. Any thoughts?
In Microsoft Access you can use the iif() function. This would look like:
SELECT *, iif(TrueLocation = PerfectLocation, 1, 0)
FROM Table1;
For what it's worth, since boolean values in MS Access are represented using the integers -1 & 0, you can also use the following to yield the same result (albeit not as readable):
select *, -(TrueLocation = PerfectLocation)
from Table1

unpaid monthly salaries (mysql +vb.net)

I have a MySQL table some thing like that
NAME salary amount month 1 month 2 month 3 month 4
john 300 300 300 0 0
maria 400 400 0 0 0
tom 380 380 380 380 0
I wanna see results in table or list view or whatever like that
name unpaid month salary amount
john month 3 300
john month 4 300
maria month 2 400
maria month 3 400
maria month 4 400
tom month 4 380
I tried code like:
sql1="select name,month1 from table where month1=0 "
sql2="select name,month2 from table where month2=0"
sql3="select name,month3 from table where month3=0"
sql4="select name,month4 from table where month4=0"
Dim Sql = String.Concat(sql1, ";", sql2 ,";",sql2,";",sql4 )
but didn't work , any help pls ?
The syntax looks a little off in your code that you have now. I do not know if this is the exact code that you have in your program, but when the SQL statements are not properly formatted nothing will happen. I have made some changes to show what may be the issue.
sql1="SELECT name, month1, amount FROM table WHERE month1=0"
sql2="SELECT name, month2, amount FROM table WHERE month2=0"
sql3="SELECT name, month3, amount FROM table WHERE month3=0"
sql4="SELECT name, month4, amount FROM table WHERE month4=0"
Dim Sql = String.Concat(sql1, ";", sql2 ,";",sql2,";",sql4 )
The issue that I see with your current formatting is that you may want to have two separate tables for the name and the pay. With the separate tables you could then use foreign keys and join the two tables to have each name on every month with the amount they were paid that month. You would also be able to group the users based off of their name using GROUP BY
With the restructured table your call would be as simple as the statement below. Since I do not know your table names I have made fake ones for them.
Dim Sql = "SELECT NameTable.name, MonthTable.month, MonthTable.amount
FROM NameTable INNER JOIN MonthTable
ON {prmarykey for name} = {foreign key for month}
GROUP BY NameTable.name"
This should give you the result that you are looking for. Let me know if you have any questions or need clarification.
Try the UNION mysql aggregate :
sql1="select name,month1 as unpaid_month from table where month1=0 "
sql2="select name,month2 as unpaid_month from table where month2=0"
sql3="select name,month3 as unpaid_month from table where month3=0"
sql4="select name,month4 as unpaid_month from table where month4=0"
Dim Sql = String.Concat(sql1, " UNION ", sql2 ,"UNION ",sql2," UNION ",sql4
How you could use spaces before column names.
I would suggest you to use UNION.
But, here's the least version of SQL;
sql = "SELECT NAME, month1 as unpaid_month, salary_amount FROM tablename WHERE month1 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month2 as unpaid_month, salary_amount FROM tablename WHERE month2 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month3 as unpaid_month, salary_amount FROM tablename WHERE month3 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month4 as unpaid_month, salary_amount FROM tablename WHERE month4 = 0"
But, the query is not good enough. What will happen if someone is paid half of its salary. And why you should get more than one record for a single person? Shouldn't there be any SUM for salary_amount and string concatenation for unpaid_month?
As it wasn't the part of your question, I can't post the advanced SQL here. Please ask for it in comment if you want that.
Please read these functions SUM() and GROUP_CONCAT() with temporary table AS TABLE. I think that you should use them for good programming.

To Fetch Top 2000 Records

I have following query
strfinal = "
TRANSFORM Format(Sum([Mandays].[Hours]),""#0.0"") AS [The Value]
SELECT
Mandays.WorkTypeCode AS WONo,
Format(Sum([Mandays].[Hours]),""0000.0"") AS Total
FROM Mandays
GROUP BY Mandays.WorkTypeCode
PIVOT UCase([Ent By]); "
the query returns more than 2048 records and then it is not possible to show in VB6 MSHFLexGrid(Limit is 2048).
How do I change query so that top 2000 records must be fetched?
The most efficient way will be to do it like this:
CurrentDB.CreateQueryDef("tmpQuery", "SELECT Top 2000 * FROM Mandays")
strfinal = "TRANSFORM Format(Sum([tmpQuery].[Hours]),""#0.0"") AS [The Value]
SELECT tmpQuery.WorkTypeCode AS WONo, Format(Sum([tmpQuery].[Hours]),""0000.0"") AS
Total FROM tmpQuery GROUP BY tmpQuery.WorkTypeCode PIVOT UCase([Ent By]); "
You could put "Top 2000" after the SELECT statement in your current code, but doing it in another query will speed things up quite a bit.
If you like, you can also put an ORDER BY statement in the CreateQueryDef so you can control which 2000 records are used.

SUM of difference in values

I need to query in MS Access the difference in value of a column to 8 and only if it is greater than 8.
So if I have a column of numbers 1-10, I want to query the sum of all the value's differences from 8. So the result of the query for the below column would be 3. (9-8)+(10-8)
SELECT Sum(([time1]-8)+([time2]-8)+([time3]-8)+([time4]-8)+([time5]-8)+([time6]-8)+([time7]-8)+([time8]-8)+([time9]-8)+([time10]-8)+([time11]-8)+([time12]-8)+([time13]-8)+([time14]-8)+([time15]-8)+([time16]-8)+([time17]-8)+([time18]-8)+([time19]-8)+([time20]-8)+([time21]-8)+([time22]-8)) AS Total
FROM tblTimeTracking
WHERE (((Month(([Day])))=Month(Now()))) AND ([time1]>8 AND[time2]>8 AND[time3]>8 AND[time4]>8 AND[time5]>8 AND[time6]>8 AND[time7]>8 AND[time8]>8 AND[time9]>8 AND[time10]>8 AND[time11]>8 AND[time12]>8 AND[time13]>8 AND[time14]>8 AND[time15]>8 AND[time16]>8 AND[time17]>8 AND[time18]>8 AND[time19]>8 AND[time20]>8 AND[time21]>8 AND[time22]) ;
Thanks,
How about:
SELECT Sum([Value]-8) As SumOfVal
FROM table
WHERE [Value]>8
Edit re complete change in original question.
It is not clear what you want
SELECT Sum(([time1]-8)+([time2]-8) ...
WHERE [time1]>8 And Time2>8 ...
Time1>8 will exclude nulls, but if that is not what you are doing, you will need to consider:
Nz([time1],0) + ...
Edit re comments
Something like:
SELECT Sum(times) FROM
(SELECT IIf(Time1>8,Time1-8,Time1) As times FROM Table
UNION ALL
SELECT IIf(Time2>8,Time2-8,Time2) As times FROM Table) As b
As b is an alias: Access SQL
UNION / UNION ALL: View a unified result from multiple queries with a union query

How can I efficiently compare string values from two tables in Access?

I have created a VBA function in Access 2010 to compare a list of terms in one table against a list of terms in another table. If the values are alike (not necessarily an exact match), I sum the value from a column from the second table for each match. TableA has approximately 150 terms. TableB has approximately 50,000 terms with a related count (integer).
Example tables:
TableA TableB
--------- ----------
ID ID
Term Term
Count
I have a simple SQL query which calls a VBA function to compare the terms and SUM the count if they have a fuzzy match.
SQL:
SELECT TableA.[Term], TermCheck(TableA.[Term]) AS [Term Count] FROM TableA ORDER BY 2 DESC;
VBA:
Option Compare Database
Public Function TermCheck(Term) As Long
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("TableB", dbOpenDynaset)
Dim ttl As Long
ttl = 0
With rst
While Not .EOF
If rst(1) Like "*" & Term & "*" Then
ttl = ttl + rst(2)
End If
.MoveNext
Wend
End With
rst.Close
Set rst = Nothing
CurrentDb.Close
TermCheck = ttl
End Function
The issue I have is that it uses about 50% of my CPU and I'd like to make it as lightweight as possible. Is there a more efficient way to accomplish this task using Access? Moving to a purely SQL alternative is not an option at this point, although it would make me happier. I'm not an Access or VBA guru, but feel that I'm missing something obvious in my query that would improve performance.
EDIT:
The expected result would list out all terms in TableA with a sum of the count column from TableB where a fuzzy match occurred.
Example Data:
TableA
-------------
1 blah
2 foo
3 bar
4 zooba
TableB
-------------
1 blah 16
2 blah2 9
3 foo 7
4 food 3
5 bar 3
Example result:
Term Count
---------------------
blah 25
foo 10
bar 3
zooba 0
SELECT
TableA.Term,
Nz(subq.SumOfCount, 0) AS Count
FROM
TableA
LEFT JOIN
(
SELECT a.Term, Sum(b.Count) AS SumOfCount
FROM TableA AS a, TableB AS b
WHERE b.Term ALike '%' & a.Term & '%'
GROUP BY a.Term
) AS subq
ON TableA.Term = subq.Term;
Edit: I used ALike and standard ANSI wild card character. That allows the query to run correctly regardless of whether it is run from SQL-89 or SQL-92 mode. If you prefer the * wild card, use this version of the WHERE clause:
WHERE b.Term Like '*' & a.Term & '*'
Note that will only do the matching correctly when run from SQL-89 mode.
On these lines?
SELECT ta.ID, tb.Term, ta.Term, tb.Count
FROM ta, tb
WHERE ta.Term Like "*" & tb.term & "*";
ID tb.Term ta.Term Count
2 hat hat 2
3 hat the hat 2
3 the hat the hat 4
4 mat mat 6
5 mat matter 6
5 matter matter 8
I typically build an expression using iif:
TestFlag:iif([TableA]![Term] = [TableB]![Term],"Same","Different")