Pivot Query in MS Access - ms-access

I have the following data in an Access table:
ID Name CAT
1 Bill Red
1 Bill Yellow
1 Bill Green
1 Bill Orange
2 Ted Purple
2 Ted White
3 Alice Indigo
3 Alice Violet
3 Alice Red
And I would like to output it as follows:
ID Cat1 Cat2 Cat3 Cat4
1 Red Yellow Green Orange
2 Purple White
3 Indigo Violet Red
Can I use pivot for this? If so, can someone suggest a suitable query? Many thanks.

Consider:
TRANSFORM First(Data.Cat) AS FirstOfCat
SELECT Data.ID, Data.Name
FROM Data
GROUP BY Data.ID, Data.Name
PIVOT "Cat" & DCount("*","Data","ID=" & [ID] & " AND Cat<'" & [Cat] & "'")+1;
Or if there is a unique record identifier field - autonumber should serve:
TRANSFORM First(Data.Cat) AS FirstOfCat
SELECT Data.ID, Data.Name
FROM Data
GROUP BY Data.ID, Data.Name
PIVOT "Cat" & DCount("*","Data","ID=" & [ID] & " AND ID_PK<" & [ID_PK])+1;

Related

Microsoft Access new columns for data based on matching values

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.

Pivot without aggregate

Please help me with this.
I have the data as this:
ID Name TotalCost
---- ---------------- ----------
1 Wash, Dry & Fold 175.00
2 Hand Wash and Fold 275.00
3 Pressing Only 25.00
4 Hand Wash and Fold 205.00
5 Dry Clean 395.00
6 Pressing Only 100.00
I would like to display my table like this:
Is this possible using PIVOT without Agrregate?
ID Wash, Dry & Fold Hand Wash and Fold Pressing Only Dry Clean
---- ---------------- ----------------- -------------- -----------
1 175.00
2 275.00
3 25.00
4 205.00
5 395.00
6 100.00
Thank you.
select *
from
(
select ID, Name, TotalCost
from Table
) src
pivot
(
sum(TotalCost)
for Name in ('Wash, Dry & Fold','Hand Wash and Fold','Pressing Only','Dry Clean' )
) piv;

Calculation of Row entries with more than 2 conditions

I would like to get sum of all the oranges in a row for a particular year and particular month and specific user. I tried couple of options with AND & OR. I am not sure how to user AND in more than 3 conditions. Below is an example grid for which e.g desired result is 2 for first rowattached example is in pic format and one of the query I am trying with is
Query
SELECT count(*) FROM `usr_fruit`
where (d1="orange" or d2=" orange " or d3=" orange " or d4=" orange ")
and year=115 and usrNo= 1 and month=2
table looks like this
usrNo d1 d2 d3 d4 month year
1 orange apple apple orange 2 115
1 apple apple apple apple 3 114
2 apple apple apple orange 2 115
2 apple apple apple apple 3 114
As you need 'orange' count in d1, ... d4 columns, try this query:
SELECT (d1='orange') + (d2='orange') + (d3='orange') + (d4='orange') AS count_in_row
FROM `usr_fruit`
WHERE year=115 AND usrNo= 1 AND month=2
Here (d1='orange') has value 1 when condition is true, and 0 otherwise. See: MySQL Equal operator
You can modify your query like below using a OR condition probably
SELECT count(*)
FROM `usr_fruit`
where 'orange' IN (d1,d2,d3,d4)
and (year=115
or usrNo= 1
or month=2);
Alternative to your query may be like:
SELECT COUNT(*) FROM `usr_fruit` where 'orange' IN (`usr_fruit`.`d1`,`usr_fruit`.`d2`,`usr_fruit`.`d3`,`usr_fruit`.`d4`) and
(year=115 or usrNo= 1 or month=2);
Based on the clarifying comment:
number of oranges in a row with usrNo =1 , month= 2, year =115
You could utilize the way MySQL interprets a boolean "true" expression as a 1 and a "false" as a 0 when put in numerical context:
SELECT (d1 == 'orange') + (d2 == 'orange') + (d3 == 'orange') + (d4 == 'orange')
FROM usr_fruit
WHERE usrNo = 1 AND month = 2 AND year = 115

How to get name and id from 2 tables where name from 1 table matches with another name in another table

I have two tables (Table 1 and Table 2)
Table 1 contains
Description Code
HOLD PINS 1
PAHARPUR SERIES COOLING TOWER,65CMH OF WATER 2
KSB MAKE CENTRIFUGAL PUMP,TYPE MEGA GC65-200 3
Table 2 contains
Item_Code Description Category
abc hold pins cat 1
aaa PAHARPUR SERIES cat2
bbb KSB MAKE cat3
I want to see if description from table 2 has the value in description in table 1, if yes then list that along with item code.
Result should be like
item_code Description
abc HOLD PINS
I think this will work fine
select item_code ,description from table2
where description in (select description from table1);
'''
it is the nested query

fixed width text file from two tables

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.