Transform/Transpose rows to columns in MS Access - vba

I have a table in Access database, I would like to transform AT_cd column into rows using SQL query in MS Access (as below result table) but I am unable to transform it correctly. I tried to transform using the below query but it is transforming the AT_cd into 200+ columns. I am not sure how to correct my query. Below is the sample table and desired result table provided. Any help much appreciated.
Table:
ID AT_cd
01 BB01A
01 IZ76N
02 AC21B
02 AX30A
02 ZA98A
03 AC21N
03 ZA76M
03 RT67T
04 QS70P
04 TR67A
04 GB45L
04 AC78M
Desired result:
ID AT_cd1 AT_cd2 AT_cd3 AT_cd4
01 BB01A IZ76N
02 AC21B AX30A ZA98A
03 AC21N ZA76M RT67T
04 QS70P TR67A GB45L AC78M
Code:
TRANSFORM FIRST(AT_cd)
SELECT [ID]
FROM Table1
GROUP BY [ID]
PIVOT AT_cd

With DCount you can get close using this query that also will sort the column values:
TRANSFORM
First(QueryQ.AT_cd)
SELECT
QueryQ.ID
FROM
(SELECT
ID,
AT_cd,
"AT_cd" & CStr(DCount("*", "TableQ", "[ID] = '" & ID & "' And [AT_cd] <= '" & AT_cd & "'")) AS Sequence
FROM
TableQ) As QueryQ
GROUP BY
QueryQ.ID
PIVOT
QueryQ.Sequence;
Edit: From Duane Hookom I was suggested this alternative method using SQL only, thus perhaps faster:
TRANSFORM
First(QueryQ.AT_cd)
SELECT
QueryQ.ID
FROM
(SELECT TableQ.ID, TableQ.AT_cd, Count(TableQ.AT_cd) AS Sequence
FROM TableQ
INNER JOIN TableQ AS TableQ_1 ON TableQ.ID = TableQ_1.ID
WHERE (((TableQ.AT_cd)>=[TableQ_1].[AT_cd]))
GROUP BY TableQ.ID, TableQ.AT_cd) As QueryQ
GROUP BY
QueryQ.ID
PIVOT
"AT_cd" & QueryQ.Sequence;

I am afraid what you want is not possible. You are trying to get results based on the order of the records in the record-list, and this cannot be done. You need to create a specific field that states the order, and then you can do it. The field that states the order would be something like:
ID AT_cd Order
01 BB01A AT_cd1
01 IZ76N AT_cd2
02 AC21B AT_cd1
02 AX30A AT_cd2
02 ZA98A AT_cd3
03 AC21N AT_cd1
03 ZA76M AT_cd2
03 RT67T AT_cd3
04 QS70P AT_cd1
04 TR67A AT_cd2
04 GB45L AT_cd3
04 AC78M AT_cd4
Once you do this, the following TRANSFORM produces your desired result:
TRANSFORM First(AT_cd)
SELECT ID
FROM Table_name
GROUP BY ID
ORDER BY ID
PIVOT Order
More information at LightningGuide.net.

Related

Case Statement with 2 columns

If Dr's name is SoinSo, then make column "Clinic Number Column" say "SO" instead of "06"
This is just a select statement not an actual change to the database.
Not sure how to code this in SQL to get this specific output.
This is the current output:
Dr Name Column | Clinic Number Column
---------------+---------------------
Doe 06
SoinSo 06
James 06
This is the desired Output:
Dr Name Column | Clinic Number Column
---------------+---------------------
Doe 06
SoinSo SO
James 06
I've tried this, but couldn't find any documentation online about doing a CASE statement for 2 columns:
When stf.DrName='SoInSo' then pc.ClinicNumberColumn='SO'
You can get the desired output from following (not tested):
SELECT
stf.DrName
,CASE WHEN stf.DrName='SoInSo' THEN 'SO' ELSE pc.ClinicNumberColumn END AS "CLINIC"
FROM
TABLE

I want to replace Normal Join in Informatica by Cross join in SQL by running a query in source qualifier?

Normal join in informatica has been done using Dummy fields added in table dev and remote. Columns in dev table are database_region,site_cd, dev_nm,
dev_locn_id, dev_typ, bond_ind , FRM_ID, AP_ID ,DUMMY_DEV
and Columns of remote are node_id and DUMMY_REMOTE.
We are creating a cross join using condition DUMMY_DEV = DUMMY_REMOTE declaring Master Columns as node_id and DUMMY_REMOTE.
However, as per client requirement we have create the Cross Join in sql. TO achieve that i am running a cross join using SQL query. When i compared the Row count and data between the Normal Join of Informatica and Cross Join of SQL, It resulted perfectly same. However the order of rows are different.
Can anyone suggest how can i achieve the exact same result?
Below is the query i am using.
select database_region,site_cd,dev_nm,
dev_locn_id, dev_typ, bond_ind , FRM_ID, AP_ID ,
node_id
from dev cross join
remote ;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Result from Informatica Normal Join
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 20MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 20MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 20MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 20MEG
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
Result of Cross Join from informatica
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 15MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 15MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 15MEG
01 AGSTAR AGSTARXAHA1-AGST AUGUSTA/80MVC7B/N65 C7 /M Y 01 20MEG
For Demonstration providing Four output rows, as Cross join results in creation of 100 000 rows.
This is too long for a comment.
SQL tables represent unordered sets. Result sets -- when there is no order by -- similarly represent unordered sets.
You can run the same query twice, on the same data, in the same database, and get the rows in a different order. SQL does not care.
If you want the results in a particular order, then use order by. If you want the results to always be returned in the same order, then use order by.

Selecting a distinct value from a 1:N dependent on a table connected to N as a 1:1

Wow that title is a doozy.
Here's the situation...
I have three tables.
APPLICATIONS: The first table is a catalog of applications, these applications contain an application ID, the Application Name, and other fields unimportant to this question.
INVENTORY: The second table is a list of deployments of these applications. The deployments contain the application name, application Id, the inventory ID, the division, the facility, and other fields unimportant to this question.
FRMP: The third table is a table created whenever an inventory record is created; this table tells us whether or not the inventory records hold confidential information. It contains an application ID, an Inventory ID, an FRMP ID, and a column that determines if the inventory record associated with it contains sensitive data.
The relations:
An application can belong to many inventory records, but an inventory record can only have one application. An FRMP record must have only one Inventory record associated to it, but an inventory record can exist without an FRMP record.
Here's what I'm trying to do, and have been struggling to do for the past two days...
I need a list of every application (by name) where for every record in which it is deployed, not a single one of those deployments contains sensitive data.
For example, if record 250 in Inventory has application name 74 and FRMP.HoldsSensitive = "No", but record 379 in Inventory has application name 74 and FRMP.HoldsSensitive = "Yes", I don't want to see application 74.
This is NOT as easy as it looks.
EDIT
Here is some example data and the preferred output.
AppID AppName Vendor
01 FooIt Goodstuff Inc
02 BarIt Greatstuff Co
03 SaltIt Sweet Inc
04 SugarIt Sweet Inc
InvID AppName Division Facility
01 FooIt Corporate Nearville
02 SaltIt Corporate Farville
03 SaltIt USA Sin City
04 SugarIt USA Sin City
05 BarIt USA Vice City
06 BarIt USA Sin City
07 FooIt USA Sin City
08 SaltIt USA Vice City
FRMPID INVID APPID HoldsSS
01 01 01 Yes
02 02 03 Yes
03 03 03 No
04 05 02 No
05 06 02 No
06 07 01 No
07 08 03 Yes
The query should only return BarIt. It should not return SugarIt because SugarIt doesn't exist within the Inventory table.
If you just wanna retrieve the application names, how 'bout
SELECT ApplicationName
FROM APPLICATIONS
WHERE NOT EXISTS
(
SELECT *
FROM FRMP
WHERE FRMP.ApplicationID = APPLICATIONS.Application_ID
AND FRMP.HoldsSensitive = 'Yes'
)
AND EXISTS
(
SELECT *
FROM INVENTORY
WHERE INVENTORY.Application_ID = APPLICATIONS.Applications_ID
)

Merge rows with same username in SSIS

I have data origination from Active Directory in a flat file that i need to export to SQL server using SSIS. My challenge is that I want to do all the operations in SSIS and have the data that is exported into the database as the final output. My flat file has several rows bearing the same username that need to be combined into one row, and then concatenating the data in one column as in my illustration below:
Username Office LocationID Dept
-------- ---------- ---------- -----
1. btan HQ 01 Acct
2. cvill South 04 HR
3. cvill North 02 HR
4. btan East 03 Acct
5. cvill West 05 HR
6. lkays HQ 01 Legal
My output should be as follows and it should all be done using SSIS:
Username LocationID Dept
-------- ---------- -----
1. btan 01, 03 Acct
2. cvill 04, 02, 05 HR
6. lkays 01 Legal
Any help will be very much appreciate.
I support the prior suggestions that this is a bad data model, and I also support the SQL (non SSIS) solution. However if you must follow this path despite our warnings, take a look at the SSIS Pivot operator. You'll need to concatenate the resulting columns into one column.
Something like this will get you a comma delimited list of the IDs
SELECT Username, STUFF(IDList, 1,2,'') AS LocationID, Dept
FROM TableName T OUTER APPLY
(
SELECT ', ' + LocationID [text()]
FROM TableName
WHERE UserName = T.UserName
FOR XML PATH('')
) T2(IDList)

SQL Update based on and Select Result From Same Table

I am going to do my best to clearly describe what I am trying to do.
I am using a DBISAM SQL database.
We sell t-shirts, and lots of different kinds. I am trying to update our product database with values from other products in the database. here is an sample:
Products Table
SKU Product LongDesc
01-S 01 Great Looking T-Shirt
01-M 01
01-L 01
02-S 01
02-M 01 Amazing Ladies T
02-L 01
03-32 03 Long t
03-34 03
03-36 03
I would like to write an update script that will update the LongDesc field on all SKU's that don't have a LongDesc but I would like that to get there LongDesc from other SKU's with the same Product
IN THE END I WOULD LIKE THE TABLE TO LOOK LIKE THIS:
SKU Product LongDesc
01-S 01 Great Looking T-Shirt
01-M 01 Great Looking T-Shirt
01-L 01 Great Looking T-Shirt
02-S 01 Amazing Ladies T
02-M 01 Amazing Ladies T
02-L 01 Amazing Ladies T
03-32 03 Long t
03-34 03 Long t
03-36 03 Long t
Thanks in advance for your help!
Try this:
UPDATE p
SET p.longdesc = pp.longdesc
FROM products p
INNER JOIN
(
SELECT a.sku, MAX(a.longdesc) AS longdesc
FROM
(
SELECT LEFT(sku FOR (POS('-', sku) - 1)) AS sku, longdesc
FROM products
) a
GROUP BY a.sku
) pp ON LEFT(p.sku FOR (POS('-', p.sku) - 1)) = pp.sku