Access SQL Transform Statement
Access SQL Transform Statement
Taken together, these things mean that we can write a function having a
single signature that can vary what it returns when it is called and then
use this function in a TRANSFORM statement's ORDER BY clause to get
one value for sorting and in its PIVOT clause to get another value for the
columns. All we need is a little state in the form of a local static variable.
Here's one way to write that function:
Function AorB(ByVal A As Variant, ByVal B As Variant) As Variant
Static LastA As Variant
If LastA <> A Then
AorB = A
LastA = A
Else
AorB = B
LastA = Empty
End If
End Function
The function AorB will be called twice for each source row. The first time
in the context of the ORDER BY, so it returns the first value (SOF_ID), and
the second time in the context of the PIVOT grouping, so it returns the
second value (SOF).
I should point out that I've never actually used this technique in a
production system, and am not sure whether it works in versions of
Access prior to 2003 (though I think it should). So, if you decide to use it,
you should test very thoroughly and be very careful. Good luck.
COMMENTS
Not bad!
A while ago, I came across a *neat* site run by a guy called "Peat" which
shows you how to do crosstabs in pure "vanilla" SQL.
Here's the link http://www.advogato.org/person/peat/diary.html?start=15
( If you're around, Peat please forgive me for posting your example, but
it's just "soooo good"! )
Here it is SELECT lakename,
COUNT(CASE WHEN year = 1996 THEN depth ELSE NULL END) AS
SY1996,
COUNT(CASE WHEN year = 1997 THEN depth ELSE NULL END) AS
SY1997,
COUNT(CASE WHEN year = 1998 THEN depth ELSE NULL END) AS
SY1998
FROM crosstab
GROUP BY lakename
"Lakename" is the row-variable and SY1996, SY1997, SY1998 are the
column variables.
Very good stuff!
- Andy
;
Andy Elvey | 2006.02.23 10:57 AM
Bob mar 13
Bob apr 14
qryCross2 results:
name 1 apr feb jan mar
Bob 11 14 12 13
Joe 4 2 1 3
qryCrossAorB:
TRANSFORM First(qryData.val) AS val
SELECT qryData.name
FROM qryData
GROUP BY qryData.name
ORDER BY AorB(qryData.id,qryData.month)
PIVOT AorB(qryData.id,qryData.month);
qryData:
SELECT tblData.name, tblData.month, tblCols.id, tblData.val
FROM tblData INNER JOIN tblCols ON tblData.month = tblCols.month
ORDER BY tblData.name, tblData.month;
DEBUG:
A: 1 B:jan AorB: 1 LastA: 1
A: 1 B:jan AorB:jan LastA:
A: 2 B:feb AorB: 2 LastA: 2
A: 2 B:feb AorB:feb LastA:
A: 2 B:feb AorB: 2 LastA: 2
A: 2 B:feb AorB:feb LastA:
A: 3 B:mar AorB: 3 LastA: 3
A: 3 B:mar AorB:mar LastA:
A: 3 B:mar AorB: 3 LastA: 3
A: 3 B:mar AorB:mar LastA:
A: 4 B:apr AorB: 4 LastA: 4
A: 4 B:apr AorB:apr LastA:
A: 4 B:apr AorB: 4 LastA: 4
A: 4 B:apr AorB:apr LastA:
Rich | 2006.05.17 11:38 PM
Hi Rich,
Thanks for the heads-up. After much trial and error, I've discovered a
couple of things about this that I probably should have discovered when I
first wrote it up.
The first thing is that the evaluation order of the ORDER BY and PIVOT
expressions can vary. Who knew? It certainly didn't vary in my earlier