I need pointed to the correct direction. I need to create a fixed width file from Access. The data will be coming from 2 tables (employer and employee). The text file must display the employer record, then the next records will contain employee data. The resulting file layout with then be used to upload into a separate system.
For example:
Employer Table
RecordID - 2 char - always 01
EmployerNumber - 6 char
EmployerName - 25 char
ReportID (pk) - Not included on text file, only used to relate employer with employee
Employee Table
RecordID - 2 char - always 02
EmployeeNumber - 4 char
EmployeeName - 25 char
ReportID (fk) - Not included on text file, only used to relate employee with employer
Resulting text file:
01012345PENGUINS
028686CROSBY
027777MALKIN
026666LEMIEUX
01012345ACME INC
021122BUGS BUNNY
021133DAFFY DUCK
029872ROAD RUNNER
Assuming that [ReportID] is integer, so the sample data looks like this for [Employer] ...
ReportID EmployerNumber EmployerName RecordID
-------- -------------- ------------ --------
1 012345 PENGUINS 01
2 012345 ACME INC 01
... and this for [Employee] ...
ReportID EmployeeNumber EmployeeName RecordID
-------- -------------- ------------ --------
1 8686 CROSBY 02
1 7777 MALKIN 02
1 6666 LEMIEUX 02
2 1122 BUGS BUNNY 02
2 1133 DAFFY DUCK 02
2 9872 ROAD RUNNER 02
the query
SELECT
RecordID & EmployerNumber & EmployerName AS RowData,
CDbl(ReportID) AS RowSort
FROM Employer
UNION ALL
SELECT
RecordID & EmployeeNumber & EmployeeName AS RowData,
CDbl(ReportID) + Val(EmployeeNumber) / 10000 AS RowSort
FROM Employee
returns
RowData RowSort
----------------- -------
01012345PENGUINS 1
01012345ACME INC 2
028686CROSBY 1.8686
027777MALKIN 1.7777
026666LEMIEUX 1.6666
021122BUGS BUNNY 2.1122
021133DAFFY DUCK 2.1133
029872ROAD RUNNER 2.9872
so the query
SELECT RowData
FROM
(
SELECT
RecordID & EmployerNumber & EmployerName AS RowData,
CDbl(ReportID) AS RowSort
FROM Employer
UNION ALL
SELECT
RecordID & EmployeeNumber & EmployeeName AS RowData,
CDbl(ReportID) + Val(EmployeeNumber) / 10000 AS RowSort
FROM Employee
)
ORDER BY RowSort
returns
RowData
-----------------
01012345PENGUINS
026666LEMIEUX
027777MALKIN
028686CROSBY
01012345ACME INC
021122BUGS BUNNY
021133DAFFY DUCK
029872ROAD RUNNER
Just save that last query in Access and then export it as text.
Your problem is a little complicated for a beginner but it has 2 parts:
You need to join the 2 tables. You should google for 'SQL Inner Joins' for a few examples.
You need to export the data in the format you want. You can do this with using the Left() function.
Assuming your tables are called Employee and Employer, consider this SQL statement:
Select
ER.RecordID &
left(ER.EmployerNumber & " ",6) &
left(ER.EmployerName & " ",25) &
EE.RecordID &
Left(EE.EmployeeNumber & " ",4) &
Left(EE.EmployeeName & " ",25) as SingleCol
From Employee EE
Join Employer ER on EE.ReportID=ER.ReportID
This query joins the 2 tables (see the Join at the bottom) and displays first the 3 fields from your Employer table followed by the 3 fields from the Employee table. The Left() statement with all the spaces pads the field with spaces. This query will return exactly 1 long text field.
Related
I'm having some trouble working out how to write a query. I want to be able to make a list of all teams, and the students within the team that are in a certain subject.
Here are the sorts of tables I have.
Team (teamID, teamName, subjectID)
Student(studentID, Student Name)
AssignTeam(AssignID, studentID, teamID)
Subject(subjectID, subjectName)
This is what I would like the output to look like.
Team 1 - Team Name
Student 1 ID - Student 1 Name
Student 2 ID - Student 2 Name
Student 3 ID - Student 3 Name
Student 4 ID - Student 4 Name
Team 2 - Team Name
Student 1 ID - Student 1 Name
Student 2 ID - Student 2 Name
Student 3 ID - Student 3 Name
Student 4 ID - Student 4 Name
Student 5 ID - Student 5 Name
Team 3 - Team Name
Student 1 ID - Student 1 Name
Student 2 ID - Student 2 Name
Student 3 ID - Student 3 Name
I'm struggling to work out how to format it in such a way to include the breaks between the groups themselves. I only really know how to make a list that looks like this
Group StuID StuName
-- ---- ----
1 1 Mike
1 2 Stacey
1 3 Jenny
2 4 Rick
2 5 Sam
3 6 Larry
3 4 Anita
I want to build the list using mySQL but it will ultimately be outputting via PHP. I was hoping to create a stored procedure which I can then call and pass the subjectID into which will then create the list.
I haven't quite worked out if the one procedure would create the list and convert to string for output or if that should be two separate queries.
Any suggestions would be much appreciated.
Thanks
This is not a mysql solution but would it not be simple enough to read the rows from mysql in PHP, and when the Group changes output the header line for that group?
See the snippet below. You'll have to make outputRow() and outputGroupHeader() generate the output in the format you need.
<?php
$lastgroup = "";
while ($row = mysqli_fetch_assoc($query))
{
if ($row['group'] != $lastgroup) {
outputGroupHeader($row['group']);
$lastgroup = $row['group'];
}
outputRow($row);
}
I have two tables in MS Access, one with foods and associated companies:
FoodID
Food
Company
1
Apple
Vino Farms
2
Orange
Citrus Co.
3
Banana
Vino Farms
and one with information about whether someone ate the food
ClientID
ClientName
Apple
Orange
Banana
1
Bob
Yes
No
Yes
2
Tyler
Yes
Yes
Yes
3
Joe
No
No
No
I'd like to write a query that creates a column populated by the company that makes the foods someone reported eating, separated by commas. If someone reports eating a more than one food made by the same company, I only want the company's name listed once:
ClientID
ClientName
AssociatedCompanies
1
Bob
Vino Farms
2
Tyler
Vino Farms, Citrus Co.
3
Joe
Any help would be greatly appreciated!
As indicated by Gustav, start by normalizing your "ate food" Table. It should look like:
1 Bob Apple
1 Bob Banana
2 Tyler Apple
2 Tyler Orange
2 Tyler Banana
You then get what you want with the following Query:
-- Group companies into one field, sepparated with commas
SELECT ClientID, ClientName, RemoveCommas(Company1 & ", " & Company2 & ", " ... & CompanyN)
FROM
( -- Convert rows (records) into columns (fields)
SELECT ClientID, ClientName
, Max(Iif(Company="Vino Farms", "Vino Farms", Null)) AS Company1
, Max(Iif(Company="Citrus Co.", "Citrus Co.", Null)) AS Company2
, ...
, Max(Iif(Company="Last_company", "Last_company", Null)) AS CompanyN
FROM
(-- Replace food by its manufacturing company
SELECT DISTINCT ClientID, ClientName, Company
FROM
Table_ate_food_normalized AS Ate
INNER JOIN
Table_food AS Comp
ON Ate.Food = Comp.Food
)
GROUP BY ClientID, ClientName
)
Notice the following relevant points:
This will only work, as you notice, for a fixed number of companies with names hardcoded in the Query. This is a very severe limitation. If these restrictions are not satisfied, I suggest that you use a TRANSFORM Query, but, you would not get the companies as a single text field with values sepparated by commas, and you would rather get them as a variable number of fields, each field having a Yes/No value (similar to your current "ate food" table).
I am assuming that the values of "food" and "Company" are each a candidate key in its Table. Otherwise, use the corresponding ID fields, and get the actual values using an inner join.
If you want to understand better the part of converting rows into columns, you may check the Query "K_rows_into_columns_1" from the database of examples dowloadable from LightningGuide.net.
You have to code the user defined VBA function "RemoveCommas()" to remove unncessary commas from the string containing the listing of companies. If unncessesary commas do not bother you, then you can do the Query without coding this functions.
If you want to code the TRANSFORM alternative that I suggested above, you may check the Query "K_rows_into_columns_2" from the database of examples dowloadable from LightningGuide.net.
I asked this question a few months back but now I'm working out of MS-Access and I'm unsure how to proceed. I have a query that lists the bldid, unitid, and resident id in separate columns. I'd like to modify the query output in Microsoft Access so that each resident that shares a building / unit shows as a new column on the same row as shown below. But since I'm limited to MS Access I can't seem to use with, cte, or rownumber. I'm at a loss as to how to do this so any help would be appreciated.
Query1
BldID
UnitID
ResidentID
1
201
John Smith
1
201
Jane Doe
1
202
Daniel Jones
1
202
Mark Garcia
2
201
Maria Lee
2
201
Paul Williams
2
201
Mike Jones
Desired Output from edited Query
BldID
UnitID
Res1
Res2
Res3
1
201
John Smith
Jane Doe
1
202
Daniel Jones
Mark Garcia
2
201
Maria Lee
Paul Williams
Mike Jones
You can use a Crosstab Query
TRANSFORM Max(Resident.ResidentID) AS MaxOfResidentID
SELECT Resident.BldID, Resident.UnitID
FROM Resident
GROUP BY Resident.BldID, Resident.UnitID
ORDER BY Resident.BldID, Resident.UnitID
PIVOT "Res" & (DCount("*",
"Resident",
"BldID=" & [BldID] & " AND UnitID=" & [UnitID] &
" AND ResidentID<'" & [ResidentID] & "'") + 1);
If you need a constant number of columns (e.g. if you want to create an Access report), then you can add an In clause to this query (before the ;):
In ("Res1","Res2","Res3","Res4","Res5","Res6")
This always creates 6 columns with the same names.
The difficulty is to get the row number per BldID/UnitID group. This is achieved by
DCount(1,
"Resident",
"BldID=" & [BldID] &
" AND UnitID=" & [UnitID] &
" AND ResidentID<'" & [ResidentID] & "'") + 1
where Resident is the name of your table or query. It counts residents having the same BldID and UnitID but having a smaller ResidentID. Adding 1 to this count yields the row number starting at 1. Then the string "Res" is prepended to build the column name.
Note that the residents are listed in alphabetical order form left to right.
I am currently working on a.Net web form solution which generates a brief service report for admins to monitor the services done by technicians.As of now , i am having some trouble in coming up with an efficient SQL (for MySQl) which return data rows along with the missing rows based on the SertvicePrtNum , which is in order.
For Example :-
This is my raw data in the table :-
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1003 8 10/06/2005
3 1005 1 21/02/2003
4 1007 7 1/06/2011
5 1010 4 4/11/2012
6 1002 2 16/01/2003
Here the ServiceRptNum , 1004 is missing in the table. So i want the db to return the result as : -
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1002 2 16/01/2003
3 1003 8 10/06/2005
- 1004 - -
4 1005 1 21/02/2003
- 1006 - -
5 1007 7 1/06/2011
- 1008 - -
- 1009 - -
6 1010 4 4/11/2012
Here , the sql additionally generated 1004,1006,1008,1009 since it cannot find those records.
Please note that the Id is automatically generated (auto_increment)while insert of the data.But the Service ReportNum is not , this is to enable the admin to add the service report later on with the manually generated report Num (report num in the hardcopy of the company Servicebook).
You basically need to invent a constant, sequential stream of numbers and then left join your real data to them. For this method to work, you need a table with enough rows in it to generate a counter big enough:
select ID, 1000+n as servicerptnum, customer_id, `Date of Service` from
(
SELECT #curRow := #curRow + 1 AS n
FROM somebigtable
JOIN (SELECT #curRow := 0) r
WHERE #curRow<100
) numbergen
LEFT JOIN
tablewithmissingservicerptnum
ON
servicerptnum = 1000+n
You need to alter some things in the code above because you never told us the name of your table with missing rptnums. You also need to utilise another table in your database with more rows than this table because the way this method works is to count the rows in the bigger table, giving each a number. If you don't have any table bigger than this one, we can probably get enough rows by cross joining a smaller table to itself or by using this table. Replace somebigtable with thistable CROSS JOIN thistable where this table is the name of the table with missing servicerptnums
If you want just the rows that are missing, add a WHERE servicerptnum is null to the end of the sql
Edit, I see you've changed your numbering from:
1001
1002
...
1009
10010
To:
1009
1010
The join condition used to be servicerptnum = concat('100', cast(n as varchar)), it is now servicerptnum = 1000+n..
Look here for ideas on how to generate a group of continuous integers, then select from that left outer join your table. You should get a row for every number but all the values will be null for the missing numbers.
I have a table named cdr_records with this columns :
TABLE: CDR_RECORDS
------------------
CDR_ID DATE CHECK_NO NAME_OF_PAYEE CHECKS_ISSUED
1 2014-01-01 3456111 John Smith 1,830.96
2 2014-01-01 3456112 Chen Lee 90,048.92
3 2014-01-01 3456113 Hen Lu 22,740.75
and I created another table that records all the data for the NCA (Notice of Cash Allocation) receive to be allocated to each check issuances.
TABLE: NCA
----------
NCA_DATE NCA_RECEIVED
2014-01-01 7,257,000.00
2014-01-01 5,564,000.00
using the query, SELECT SUM(NCA_RECEIVED) would result 12,821,000
I want to display the BANK_BALANCE of each records of check issuance by subtracting the
sum of 12,821,000 to each check issuances to obtain the balance as follows:
12,821,000 - 1,830 = 12,819,170
12,819,170 - 90,048.92 = 12,729,121.08
and so on illustrated below.
CDR_ID DATE CHECK_NO NAME_OF_PAYEE CHECKS_ISSUED BANK_BALANCE
1 2014-01-01 3456111 John Smith 1,830.96 12,819,170.00
2 2014-01-01 3456112 Chen Lee 90,048.92 12,729,121.08
3 2014-01-01 3456113 Hen Lu 22,740.75 12,706,380.33
Can anyone help me how to query to obtain the running balance deducted to each check issuances?
Any help would be great appreciated.. thanks
Thanks for the answer and it really solved on how to display the running balance..
But another problem is that I store the data from different tables with foreign keys as follows :
Table: issue_details
issue_id (PK) issue_date check_no issue_amount
1 2014-01-01 345611 1,500.00
2 2014-01-01 345612 21,000.12
Table: cdr_records
cdr_id (PK) issue_id (FK)
1 1
2 2
Table: nca
nca_no (PK) nca_date nca_received
111 2014-01-01 7,257,000.00
112 2014-01-01 5,564,000.00
Im new to sql and Im not good at joining tables when performing calculations. How to perform the same calculation but of relational tables ?
You can do this with variables. The key is initializing the total to the value from the `nca table.
select r.*,
(#tot := #tot - checks_issued) as bank_balance
from (select #tot := sum(nca_received) as nca
from nca
) vars cross join
cdr_records r
order by r.date, r.check_no;