Add column to table form to show value from a query - ms-access

I have table x, where x.b is the primary key:
+-----+-----+
| a | b |
+-----+-----+
| xyz | 123 |
| abc | 456 |
| abc | 999 |
+-----+-----+
Table y, where y.b is the foreign key for x.b:
+----+-----+-------+
| ID | b | c |
+----+-----+-------+
| 1 | 123 | x105 |
| 2 | 123 | a309 |
| 3 | 456 | b123 |
| 4 | 999 | q234 |
| 5 | 999 | z525 |
+----+-----+-------+
A query yQuery based on y to find the value of c for the highest ID for each b, which results in:
+----+-----+-------+
| ID | b | c |
+----+-----+-------+
| 2 | 123 | a309 |
| 3 | 456 | b123 |
| 5 | 999 | z525 |
+----+-----+-------+
I have a form xForm that's currently displaying table x. I want to add a column that shows the c result from yQuery, so that xForm would look like this:
+----+-----+-------+
| ID | b | c |
+----+-----+-------+
| 2 | 123 | a309 |
| 3 | 456 | b123 |
| 5 | 999 | z525 |
+----+-----+-------+
I tried adding a textbox to xForm where the control source of the textbox is:
=[yQuery]![c]
But that just gave me a column of #Name? errors. I'm not sure how to set up the textbox so that its source is the xForm!ID field.

One option would be to have the form bound to a query that pulls the information from table [x] joined with query [yQuery] on [ID]. However, if [yQuery] has a GROUP BY clause then any query that incorporates [yQuery] might produce a recordset that is not updateable.
Another option would be to use a DLookup() as the Control Source for the textbox in question, something like
=DLookup("c","yQuery","ID=" & [ID])

you could just use this dlookup instead:
=DLookup("[c]","yQuery","[b] = " & [Control Name for B in your form])
or maybe
=DLookup("[c]","yQuery","[b] = """ & [Control Name for B in your form] & """")
if b is not numeric

Related

How to bring columns to a table from another table by the Id?

I have this tables People, Ticket, and Report.
+----------+-------+-----+
| idPeople | Name | Age |
+----------+-------+-----+
| 1 | Name1 | 21 |
| 2 | Name2 | 37 |
| 3 | Name3 | 28 |
+----------+-------+-----+
I would like to replace the ForeingKey idPeople with columns Name and Age from People table.
+----------+------------+------------+----------+
| idTicket | ticketCol2 | ticketCol3 | idPeople |
+----------+------------+------------+----------+
| 5 | True | 01/06/99 | 1 |
| 6 | False | 01/06/99 | 2 |
| 7 | True | 01/06/99 | 4 |
+----------+------------+------------+----------+
In the Report table replace the Foreing Key idTicket with ticketCol2, Name, Age from the previous table Ticket with replaced columns (idPeople by Name, Age).
+----------+----------+------------+------------+
| idReport | idTicket | ReportCol3 | ReportCol4 |
+----------+----------+------------+------------+
| 1 | 5 | 01/06/99 | blabla |
| 2 | 7 | 01/06/99 | asdfdd |
| 2 | 6 | 01/06/99 | fooboo |
+----------+----------+------------+------------+
And I the result should be like this table and must be done in one query.
+----------+------------+------------+------------+------------+------+-----+
| idReport | ticketCol2 | ticketCol3 | ReportCol3 | ReportCol4 | Name | Age |
+----------+------------+------------+------------+------------+------+-----+
| 1 | 01/06/99 | abcd | blabla | 123456 | Name | 20 |
| 2 | 01/06/99 | bcda | asdfdd | 321456 | Name | 23 |
| 3 | 01/06/99 | asdf | fooboo | 123456 | Name | 28 |
+----------+------------+------------+------------+------------+------+-----+
I Have tried replacing the foreingkeys with LEFT JOIN and bringing some columns Name and Age to the Ticket table but now the last part where I should replace idTicket with Columns from Ticket is not working.
I have read about the nested JOINs but I cannot understand it very well, I would really appreciate some idea of how I can do it or what should I investigate. Are nested Joins the right way?
The query that I've tried to accomplish the Table Ticket.
SELECT Ticket.ticketCol2, Ticket.ticketCol3, p.Name 'Name', p.Age 'Age'
from Ticket
left join people p on (Ticket.idPeople=p.idPeople);
Try something like this:
SELECT Report.idReport,
Ticket.ticketCol2,
Ticket.ticketCol3,
Report.ReportCol3,
Report.ReportCol4,
People.Name,
People.Age
FROM People
LEFT JOIN Ticket ON Ticket.idPeople = People.idPeople
LEFT JOIN Report ON Report.idTicket = Ticket.idTicket
Like #RiggsFolly said, the Ticket.idPeople won´t match to the People.idPeople, so this will not match any rows.

How to make a pivot table by multiple unique ID numbers?

I'm trying to break up a SQL table that needs to take a users name and find the unique user ID's from up to 4 systems.
The data is currently like this:
| Name | User_ID |
-----------------
| A | 10 |
| A | 110 |
| A | 1500 |
| A | 4 |
| B | 20 |
| B | 100 |
| B | 2 |
| C | 10 |
I need to pivot it around the user's name to look like this (the id's don't need to be in numerical order as the SYS#_ID for each doesn't matter):
| Name | SYS1_ID | SYS2_ID | SYS3_ID | SYS4_ID |
------------------------------------------------
| A | 4 | 10 | 110 | 1500 |
| B | 2 | 20 | 100 | NULL |
| C | 10 | NULL | NULL | NULL |
This is the code I have tried on MySQL:
PIVOT(
COUNT(User_ID)
FOR Name
IN (SYS1_ID, SYS2_ID, SYS3_ID, SYS4_ID)
)
AS PivotedUsers
ORDER BY PivotedUsers.User_Name;
I'm unsure if PIVOT works on MySQL as I keep getting an error "PIVOT unknown". Is there a way to find the values that each user has and if they do not appear in the table already add them to the next column with a max of 4 values?

MS Access Report Field Value as Heading with Other Field Values Beneath in Table

In a Microsoft Access report, how can I display each record of a field as a column heading with the records of other fields in that columns records beneath it.
My query gives me data in the following format:
| ID | Item | Item Characteristic 1 | Item Characteristic 2 | Other Fields |
|:--:|:------:|:---------------------:|:---------------------:|--------------|
| 22 | Code 1 | Blue | 48 | … |
| 22 | Code 2 | Red | 50 | … |
| 22 | Code 3 | Green | 99 | … |
I'd like to have on my report to look something like this:
| Heading | Data True to All Records1 | More Data True to All Records2 | |
|:---------------------:|:-------------------------:|:------------------------------:|:------------:|
| ------------ | ------------ | ------------ | ------------ |
| Item | Code 1 | Code 2 | Code 3 |
| Item Characteristic 1 | Blue | Red | Green |
| Item Characteristic 2 | 48 | 50 | 99 |
| Other Fields | … | … | … |
| ------------ | ------------ | ------------ | ------------ |
| Footer | Data True to All Records3 | More Data True to All Records4 | |
Currently, I can only get data in the format:
| Heading | | |
|:-------:|:-----:|:--:|
| ---- | | |
| Code 1 | Blue | 48 |
| | | |
| Code 2 | Red | 50 |
| | | |
| Code 3 | Green | 99 |
| --- | | |
| Footer | | |
Where each record is resulting in a new 'row' in the report.
Can anyone help?
Table needs a unique record identifier - an autonumber type field should serve, then consider the following.
Query1:
SELECT RecID, ID, "Item" AS Category, Item AS Data FROM Tablename
UNION SELECT RecID, ID, "ItemChar1", ItemChar1 FROM Tablename
UNION SELECT RecID, ID, "ItemChar2", ItemChar2 FROM Tablename;
Query2:
TRANSFORM First(Query1.Data) AS FirstOfData
SELECT Query1.ID, Query1.Category
FROM Query1
GROUP BY Query1.ID, Query1.Category
PIVOT Query1.RecID;
For posterity, I resolved this by setting out a table of unbound labels.
I gave each of these labels a control name of x-y, where x was the column number and y was the row number.
I then looped through each column and row and changed the caption of the label to the value from my RecordSet.
(Form("FormName").Controls.Item(x & "-" & y)).Caption = .Fields("FieldName")

how to maintain table orignal order after using dense_rank() in sql server

I have a table :-
ID | name | address | code
-----+---------+-----
1 | b | b-11 | 111
2 | b | b-11 | 123
3 | a | a-11 | 456
4 | a | a-11 | 789
I need the output like : -
id | name | address | code | Addressid
-----+---------+------+----------
1 | b | b-11 | 111 | 1
2 | b | b-11 | 123 | 1
3 | a | a-11 | 456 | 2
4 | a | a-11 | 789 | 2
When I use the following SQL statement I get the desired format but the order of the table gets changed. Can someone tell me how to get AddressID column values without changing the table order.
select
id, name, address, code,
dense_rank() over (order by name,address) as addressid
from
table1
with the above code I get the wrong output as -
id| name | address | code | Addressid
--+------+---------+------+----------
3 | a | a-11 | 456 | 1
4 | a | a-11 | 789 | 1
1 | b | b-11 | 111 | 2
2 | b | b-11 | 123 | 2
As I said - you don't have any order, unless you explicitly specify it - so that's all you need to do - specify the ordering you want to have by adding order by id to your existing query:
select
id, name, address, code,
dense_rank() over (order by name,address) as addressid
from
table1
order by
id

Select duplicate and keep the oldest (not based on ID)

Thanks for your help i'm stuck on this problem.
Let me explain it, i have this kind of table :
| domain | creationdate | value 1 | value 2 |
|--------|---------------------|---------|---------|
| abc | 2013-05-28 15:35:01 | value 1 | value 2 |
| abc | 2013-04-30 12:10:10 | value 1 | value 2 |
| aaa | 2011-04-02 13:10:10 | value 1 | value 2 |
| bbb | 2012-02-12 10:48:10 | value 1 | value 2 |
| bbb | 2013-04-15 07:15:23 | value 1 | value 2 |
And i want to select (with subqueries) this :
| domain | creationdate | value 1 | value 2 |
|--------|---------------------|---------|---------|
| abc | 2013-04-30 12:10:10 | value 1 | value 2 |
| aaa | 2011-04-02 13:10:10 | value 1 | value 2 |
| bbb | 2012-02-12 10:48:10 | value 1 | value 2 |
I tried to do a combinaison of subqueries with IN/NOT IN in WHERE clause and group by/having but i'm not able to obtain a proper result.
I also have another question to ask, if someone already faced this kind of problem i would be glad to hear how he managed to figure it out.
The records in the first table you see above are frequently (every ten mins) deleted/inserted. My aim is to make a copy (or maybe a view) of the result (without the duplicates entries) which will be used 24/7 by a postfix mail server. I heard that big views (with many subqueries) decreases performances which means a table would be a preferable option. The thing is if i have to make a new table every ten mins there will be a little down time and postfix will not be able to read the table.
Waiting for your advices, thanks already.
EDIT :
Based on #Ed Gibbs answer, there is a better sample :
Source table :
| domain | creationdate | value 1 | value 2 |
|------------|---------------------|---------|---------|
| google.com | 2013-05-28 15:35:01 | john | mary |
| google.com | 2013-04-30 12:10:10 | patrick | edward |
| yahoo.fr | 2011-04-02 13:10:10 | britney | garry |
| ebay.com | 2012-02-12 10:48:10 | harry | mickael |
| ebay.com | 2013-04-15 07:15:23 | bill | alice |
With your query the result is the source table.
Desired result :
| domain | value 1 | value 2 |
|------------|---------|---------|
| google.com | patrick | edward |
| yahoo.fr | britney | garry |
| ebay.com | harry | mickael |
I want to keep the oldest domain (with the min creation date) with its own value1 and 2.
New question !
I made a view of the desired result based on your anwser.
The result look like this :
| domain | value 1 | foreign_key |
|------------|---------|-------------|
| google.com | patrick | X |
| yahoo.fr | britney | Y |
| ebay.com | harry | Z |
I also have a table with this kind of entries :
| email | value 1 | foreign_key |
|--------------------|---------|-------------|
| john#google.com | patrick | X |
| john#google.com | britney | Y |
| harry#google.com | mary | X |
| mickael#google.com | jack | X |
| david#ebay.com | walter | Z |
| alice#yahoo.com | brian | Y |
Assume that (in this sample) emails %#google.com from Y foreign_key aren't good records (only %google.com from X foreign are the good ones and also because its domain is the one i choose with the creationdate selection) how could i manage to select only emails from domain/fk referenced in my new view ?
Desired result :
| email | value 1 | foreign_key |
|--------------------|---------|-------------|
| john#google.com | patrick | X |
| harry#google.com | mary | X |
| mickael#google.com | jack | X |
| david#ebay.com | walter | Z |
| alice#yahoo.com | brian | Y |
I tried with a CONCAT('%','#',domain) and a foreign_key=foreign_key join but it doesn't give me what i want.
Based on your sample data and results, a GROUP BY will give you the results you're after:
SELECT
domain,
MIN(creationdate) AS creationdate,
value1,
value2
FROM mytable
GROUP BY domain, value1, value2
Addendum: #Arka provided updated sample data where the value 1 and value 2 columns have different values (in the original they were the same). That changes the query to this:
SELECT domain, creationdate, value1, value2
FROM mytable
WHERE (domain, creationdate) IN (
SELECT domain, MIN(creationdate)
FROM mytable
GROUP BY domain)
The subquery gets a list of the earliest creationdate for each domain, and the outer query only selects rows where the domain and creationdate match the subquery values.