Access: Sum values from multiple and variable columns - ms-access

In table1, I have the field Pianificato and a lot of columns with name Wxx_yyyy.
I need to update Table1.Pianificato as sum of all the W-columns that satisfy a certain criteria.
The criteria that I should apply, is that xx is higher than a certain value.
In this example, xx > 2. So Table1.W01_2018 and Table1.W02_2018 will not be considered in the sum.
I don't think that this complex request can be satisfied by a Query. So I think the only way is VBA.

If you want to avoid VBA and there are no more than 50 Wxx fields, a UNION can rearrange fields. There should be a unique identifier field - an autonumber will serve. Since I suspect there are 52 Wxx fields and you don't want W01_2018 and W02_2018 fields, exclude those 2.
SELECT ID, W03_2018 AS Data, "W03_2028" AS WkYr FROM tablename
UNION SELECT ID, W04_2018, "W04_2018" FROM tablename
. . .
UNION SELECT ID, W52_2018, "W52_2018" FROM tablename;
Then use that query in an aggregate query:
SELECT ID, Sum(Data) AS Planificato FROM UnionQuery GROUP BY ID;
Issue arises when you want to do calculations for a different set of weeks and/or year - have to modify the UNION.
A VBA approach may be more desirable, like:
Sub CalcPlanificato()
Dim rs As DAO.Recordset
Dim lngP As Long, x As Integer
Set rs = CurrentDb.OpenRecordset("SELECT * FROM Table1;")
While Not rs.EOF
For x = 3 To 52
lngP = lngP + rs.Fields(x)
Next
rs.Edit
rs!Planificato = lngP
rs.Update
rs.MoveNext
lngP = 0
Wend
End Sub
Code assumes fields are in order in table as shown in example. Assumes Planificato is the first field. Assumes there are 52 Wxx fields. Wxx fields are referenced by index and W03_2018 is in column 4 which is index 3.

Related

How to merge SQL queries to use result first one?

I am trying to merge the below 2 MySQL statements to return just one result.
This first query returns a list of companyId's & name's:
SELECT gap.user_companies.companyId, gap.companies.name
FROM gap.user_companies
INNER JOIN gap.users
ON gap.user_companies.userId = gap.users.userId
INNER JOIN gap.companies
ON gap.user_companies.companyId = gap.companies.companyId
WHERE gap.users.username = 'tester';
The next query that I'm running returns a list of dates, but they need to use the companyId value from the above query.
Here is what I have so far:
SELECT creationdate, meetingdate FROM reports
WHERE reportId IN (
SELECT reportId FROM report_companies
WHERE companyId = 123
)
ORDER BY creationdate;
So I need to combine the above queries to return name from the COMPANIES table, as well as creationdate & meetingdate from the REPORTS table.
Belwo is some pseudo-code to help explain what the catch is:
The second query will need to use the companyId result of the first query.
The first query will return multiple records, so I need to update my WHERE companyId = 123 to something like
WHERE companyId IN (the companyId part of the first query's result)
Can someone please show how to merge these?

Append Query - Multiple Tables into Single Table

I have 8 queries all with the same design etc to make a new table but for different criteria's and would like to append them into one single table.
Is there any way with VBA code or possibly UNION to do this?
SELECT tbl_SCCMQ.CONTRACT_ACCOUNT_NUMBER, tbl_SCCMQ.BP_Partner, tbl_SCCMQ.CONTRACT_NUMBER, tbl_SCCMQ.BILL_TO_DATE, tbl_SCCMQ.CONTRACT_START_DATE, tbl_SCCMQ.AGEING_DATE, tbl_SCCMQ.DateDiff, tbl_SCCMQ.PAYMENT_TYPE, tbl_SCCMQ.BP_Type, tbl_SCCMQ.[Next Bill Due Date], tbl_SCCMQ.[BAND], tbl_SCCMQ.RAG, tbl_SCCMQ.BILL_STATUS INTO tbl_01_Resi_CCQ_R1_4_Never_Billed_NoSS
FROM tbl_SCCMQ
WHERE (((tbl_SCCMQ.BP_Type)="B2C") AND ((tbl_SCCMQ.RAG) Like "R*") AND ((tbl_SCCMQ.BILL_STATUS)="First") AND ((tbl_SCCMQ.BILL_BLOCK) Is Null) AND ((tbl_SCCMQ.BILL_LOCK) Is Null) AND ((tbl_SCCMQ.INVOICE_LOCK) Is Null));
Here are two tables,
qry_01_Resi_CCQ_R1_4_Never_Billed_NoSS
qry_02_SME_CCQ_R1_4_Never_Billed_NoSS
and would like them all importing into main table "Data"
I am quite new to Access and VBA etc.
your question looks like you know how to solve the problem.
Note: queries 1 to 8 must have the same number of fields and datatypes must be consistent for each field's ordinal position (asserted in your question.)
SQL syntax to create a new table (Data) from the queries:
select *
INTO Data
from (
select * from query1
union all
select * from query2
union all
...
union all
select * from query8
) as queryData
or
SQL syntax to append data to existing table:
INSERT INTO Data
select *
from (
select * from query1
union all
select * from query2
union all
...
union all
select * from query8
) as queryData
VBA syntax to run the query in code:
dim db as dao.database: set db = Currentdb
dim strSQL as string
strSQL = "...." ' as above
db.execute strSQL

SQL Query for Getting a Duplicate Record and Show it in One Row in Gridview

So I need to show a data with duplicate record into one row only.
Please see the image Record
The Employee has more than one job but I only need to see the amployees empno, firstname, last name, enity and location so I only need one row of a record.
I tried using the SELECT DISTINCT but it's not working.
Here's my codes
Protected Sub BindUsersGrid()
Dim Con As New SqlConnection
Con = getConn()
Dim ds As DataSet = GetRecord("SELECT DISTINCT MASTERID, USERID, EMPNO, LASTNAME, FIRSTNAME, ENTITY, LOCATION, EMAIL, BDATE, SEX, CONTACT_NO, IS_RESIGNED, LOCALNAME, " & _
"REGION, COUNTRY " & _
"FROM EMP_MASTERTBL " & _
"ORDER BY LASTNAME, FIRSTNAME, MASTERID")
Me.myDataTable = ds.Tables(0)
Me.gvUsers.DataSource = Me.myDataTable
Me.gvUsers.DataBind()
Session("gvData") = myDataTable
End Sub
What could be the problem to my codes? Can you give me another ideas or sample or another code to use for this?
Thank you very much.
When you do a SELECT DISTINCT, the database will return records which are distinct with regard to all the columns. This means that if you want records which are distinct with regard to 4 columns, but you select 5, then you could get what appears to be duplicates in your result set. From what you told us, the following query might be along the lines of what you want:
SELECT DISTINCT EMPNO, LASTNAME, FIRSTNAME, ENTITY, LOCATION
FROM EMP_MASTERTBL
ORDER BY LASTNAME, FIRSTNAME

Difference of field value between two records in same table

I have table1 and it has meter reading field. I want to calculate difference between meter reading record1 and meter reading record 2.
Assuming that you have a contiguous ID field in table1 the following query would give you the desired results:
SELECT T1.ID, T1.MeterReading, T2.MeterReading, [T2].[MeterReading]-[T1].[MeterReading] AS Difference
FROM tbl AS T1, tbl AS T2
WHERE (((T1.ID)=[T2].[ID]-1));
However, if ID is of autonumber type you risk missing out some numbers and losing contiguity, so I would suggest using number type for ID and using some code to ensure contiguity.
I have assumed names of table and fields, so obviously you should change those to fit your schema.
Dim rs AS new ADODB.Recordset
Dim PrevReading AS Long
rs.CursorLocation = adUseClient
rs.Open "SELECT * FROM tblReadings ORDER BY ReadingDate",CurrentProject.Connection,adOpenKeyset, adLockOptimistic
Do While Not rs.Eof
rs.Field("Difference")=rs.Field("MeterReading") - PrevReading
PrevReading = rs.Fields("MeterReading")
rs.MoveNext
Loop
rs.Close

Returning row number on MS Access

I have 4 tables, from which i select data with help of joins in select query...I want a serial no.(row number) per record as they are fetched. first fetched record should be 1, next 2 and so on...
In oracle the equiavelent in RowNum.
The answer by Brettski is ASP flavored and would need a lot of editing.
SELECT DCOUNT("YourField","YourTable","YourField <= '" & [counter] & "'")
AS RowNumber,
YourField as counter FROM YourTable;
Above is your basic syntax. You are likely to find this runs very slow. My typical solution is a bucket table with Autonumber field. That seems kludgy, but it gives me control and probably in this case it allows speed.
Using a sorted Make Table Query in Access, I use the following (wouldn't work if you look at the Query, as that would increment the number when you don't want it to)....
setRowNumber 'resetting increment before running SQL
DoCmd.RunSQL ... , rowNumber([Any Field]) AS ROW, ...
'Increment Number: Used to create temporary sorted Table for export
Private ROWNUM As Long
'dummyField: must take an input to update in Query
Public Function rowNumber(ByVal dummyField As Variant, Optional ByVal incBy As Integer = 1) As Long
ROWNUM = ROWNUM + incBy 'increments before value is returned
rowNumber = ROWNUM
End Function
Public Function setRowNumber(Optional ByVal setTo As Long = 0) As Long
ROWNUM = setTo
setRowNumber = ROWNUM
End Function
With the following table
SET NOCOUNT ON
CREATE TABLE people
(
firstName VARCHAR(32),
lastName VARCHAR(32)
)
GO
INSERT people VALUES('Aaron', 'Bertrand')
INSERT people VALUES('Andy', 'Roddick')
INSERT people VALUES('Steve', 'Yzerman')
INSERT people VALUES('Steve', 'Vai')
INSERT people VALUES('Joe', 'Schmoe')
You can use a sub query to create the counting row:
SELECT
rank = COUNT(*),
a.firstName,
a.lastName
FROM
people a
INNER JOIN people b
ON
a.lastname > b.lastname
OR
(
a.lastName = b.lastName
AND
a.firstName >= b.firstName
)
GROUP BY
a.firstName,
a.lastName
ORDER BY
rank
The problem with this method is that the count will be off if there are duplicates in your results set.
This article explains pretty well how to add a row counting column to your query.