I have a query in MS Access that looks like the table on the left. For nicer readability, I would prefer it like the table on the right:
Item Buyer Item Buyer
------------------- -------------------
Hamburger Tim Hamburger Tim
Hamburger Alice Alice
Hamburger Frank Frank
Hamburger Greg Greg
Hot dog Frank Hot dog Frank
Hot dog Mary Mary
Hot dog Susan Susan
Apple Tim Apple Tim
Banana Susan Banana Susan
Banana Alice Alice
This is purely for visual aid, so I don't think it's necessary to change anything in the actual query. Rather, I would simply use some sort of conditional format, so that duplicated cells (except the first ones) in the Item column have an "invisible" font. I tried using "Expr1: Format([Item],[white])", but I couldn't make it work, much less work only for duplicates.
Any help will be appreciated
Method in query (not as complicated as I thought), however, could perform slowly in large dataset:
SELECT IIf(DCount("*", "TableName", "Item='" & [Item] & "' AND Buyer<'" & [Buyer] & "'") = 0, [Item], Null) AS I, Buyer AS B
FROM TableName
ORDER BY Item, Buyer;
More stable approach would be to build a report and set textbox HideDuplicates property.
Related
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 have a table where one field contains a free to choose text. Some of these texts are identical, some are not. So as an example, this may look like this:
Joe
Jim
Jack
Jack
Jim
Jack
Jane
Now I want to list all the contents of these fields, but compared on a content level so that every data is shown only once. Means the result from my data have to look like this:
Joe
Jim
Jack
Jane
The double-entries Jim and Jack are shown only once although they are contained more often.
My question: is there a SQL-statement which covers this or do I have to filter these data in the result?
Thanks!
Select distinct fieldname from your_table_name
SELECT DISTINCT nameField
FROM YourTable
Hopefully this will make sense...I have a table in Access 2010 that contains a list of suppliers and their point of contacts at the supplier and where I work. The POCs vary in number, anywhere from 1-4 up to this point. The table is set up so each POC is on a separate line.
The supplier could have one contact but work could have three different contacts and vice versa.
What I want to happen is when I select a value from a combobox on a form, all the related POCs need to be shown instead of cycling through them one by one.
For example, Supplier1 has two POCs at their facility and we have three at our facility. I would like to have the combobox find Supplier1 in the table and then show all the contacts for that supplier (their facility and ours) in a textbox.
The user will be able to edit the contact information and, if it is not too difficult, would be able to add/delete a contact.
I'm sure a question similar to this one has been asked before, however I have been unable to word it correctly to find a solution through google searches/this website. I'm comfortable enough with VBA to use that if required but am by no means an expert. I am completely unfamiliar with SQL and would like to avoid going that direction if at all possible.
I have to be careful with any data I provide but will do what I can if you need to see the data or anything like that.
Supplier Code Part Supplier Contact Procurement Contact QC Contact
Ajin AKVN Patrick Yong Jack
Ajin AKVN Chase Yong Jack
Autoliv AMNP Seatbelt Daryl James Lewis
Bosch AG48 Hancheul Kevin
Carlex AKJ5 QTR Glasses Bob Joy Zack
Continental ANKC Jacob
KSR C03A05 Brake Pedal Jose Paul David
KSR C03A05 Brake Pedal Jose Paul Gary
KSR C03A05 Brake Pedal Jose Paul Steven
KSR AG5Z Accelerator Pedal Jack Paul David
KSR AG5Z Accelerator Pedal Jack Paul Gary
KSR AG5Z Accelerator Pedal Jack Paul Steven
KSR AG5Z Accelerator Pedal Cory Paul David
KSR AG5Z Accelerator Pedal Cory Paul Gary
KSR AG5Z Accelerator Pedal Cory Paul Steven
Your table needs heavy normalization (see e.g. What is Normalisation (or Normalization)? or http://r937.com/relational.html )
I would suggest (Note: I'm not sure about the Supplier/Code/Part relation) :
- tSupplier
SupplierID SupplierName
1 Ajin
2 KSR
- tParts
PartID SupplierID Code Part
1 1 AKVN
2 2 C03A05 Brake Pedal
- tContactTypes
TypeID Type
1 Supplier
2 Procurement
3 QC
- tContacts
ContactID SupplierID TypeID ContactName
1 1 1 Patrick
2 1 1 Chase
3 1 2 Yong
4 1 3 Jack
and so on.
The first column of each table is the primary key, an autonumber field.
All other ID columns are foreign keys, linking to a parent table.
Now you can have a combobox for the Supplier, which gives the SupplierID.
With that, you can filter the Contacts and show them in a datasheet subform.
Either all in one table, with the ContactTypes as column, or in three subforms, each filtered by one ContactType.
To be able to add new contacts, use the BeforeInsert event to assign the current SupplierID.
I have a matrix on my report that is displaying a data set that contains one row for each person in a company:
Company Position Name
------- -------- -----
Acme Inc. CEO Bob
Acme Inc. COO Alice
Beta Corp. CEO Frank
Beta Corp. CTO Rob
Beta Corp. COO Bill
(etc)
The matrix has a column grouping for Position, and a row grouping for Company. The final report looks like this:
Company CEO CTO COO
-----------------------------------------
| Acme Inc. | Bob Alice |
| Beta Corp | Frank Rob Bill |
| Foo, Inc. | Paul |
| Bar Corp | Mary |
I want to add a footer row at the bottom of the matrix that counts how many CEOs, CTOs, etc there are.
-------------------------------------
People in role | 3 2 2
How do I do this in SQL Reporting Services 2005? Unfortunately, Matrix controls in SSRS 2005 don't seem so support footer rows like Table controls do. I think the solution will involve some trickery involving row groups, but I don't know enough about the Matrix control to figure it out.
In the Design view, right click on the "Company" cell and select Add Total-->After.
A new row will be added as a footer with "Total" in the left most cell. To the right of totalm in the Title Column, enter the following expression:
=COUNT(Fields!Name.Value)
Preview the report and the Totals will be displayed exactly as you're looking for.
Update
The above answer is for SSRS 2008. Since you're using SSRS 2005, take a look at Technique #5 in the following link: http://www.simple-talk.com/sql/reporting-services/advanced-matrix-reporting-techniques/
Simplest Solution I could find out was
=SUM(iif(Fields!Name.Value<>"",1,0))
where Fields!Name is data field in Matrix.
Please Mark this as an answer you find this helpful
Can you try to use InScope function?
For example,
=IIF(InScope("nameOfColumnGrouping"), Sum(yourField.Value), do something)
You may have to specific the scope on Sum function also.
For example,
=IIF(InScope("nameOfColumnGrouping"), Sum(yourField.Value,"datasetName/groupName"), do something)
Hope this help!
Hello I am dealing with some unfriendly import files which import as:
timestamp position name
001 2 Jon
001 3 Bob
001 1 Ann
001 4 Mike
002 1 Joe
002 2 Sue
003 1 Jeff
004 5 James
004 1 Andy
004 2 Beth
004 4 Mitch
004 3 Chris
And would like to create a new table that displays thusly:
timestamp position1 position2 position3 position4 position5
001 Ann Jon Bob Mike
002 Joe Sue
003 Jeff
004 Andy Beth Chris Mitch James
By browsing this forum the closest I have come to a solution is:
SELECT pos1.timestamp, pos1.name AS position1, pos2.name AS position2
FROM table1 AS pos1 INNER JOIN table1 AS pos2
ON pos1.timestamp = pos2.timestamp
WHERE (((pos1.position)=1) AND ((pos2.position)=2))
I cannot figure out how to expand this to my specs, any help is much appreciated.
Try something like this
TRANSFORM First(Table.[name]) AS FirstOfname
SELECT Table.[timestamp]
FROM [Table]
GROUP BY Table.[timestamp]
PIVOT Table.[position];
I created this using the MS Access Cross Tab Query Wizard.
Also have a look at
What is a CrossTab Query?
Some better explenation.
Click the Create tab.
Click the Query Wizard.
Select Second Option (Crosstab Query
Wizard) and hit OK.
Select the table for your input, and
hit next.
Select Timestamp and click the arrow
(single) pointing fromleft to right,
and hit next.
Select position and hit next.
name will be the remaining field,
Select First (default is count), and
hit next.
Hit finish.
It should have saved a query called Table_Crosstab (or something similar).
Right click this and select design view.
On the view button, select Sql View.
You should see something similar to
TRANSFORM First(Table.name) AS FirstOfname
SELECT Table.timestamp, First(Table.name) AS [Total Of name]
FROM [Table]
GROUP BY Table.timestamp
PIVOT Table.position;
From the second line remove
, First(Table.name) AS [Total Of name]
so that you end up with
TRANSFORM First(Table.name) AS FirstOfname
SELECT Table.timestamp
FROM [Table]
GROUP BY Table.timestamp
PIVOT Table.position;
And that should be it. Save and you are ready.
Your new table is a bad design. What happens when there is a sixth and a seventh person in the incoming data? It will also be difficult to work with when you need to pull out all the data by a specific person as you will then need to query five columns.