I would like to UNPIVOT some columns of data which I've managed to do with no problem, the issue I have is that I need to do a calculation between columns before unpivotting the data - is this possible? I've tried to do a SUM but I keep getting a "missing comma" error so I suspect something is not right.
This is the syntax I am using:
select
unpvt.YY,
substr(unpvt.ACCT,1,6) CC,
substr(unpvt.ACCT,7,5) Nom,
substr(unpvt.ACCT,12,6) Det,
substr(unpvt.ACCT,18,4) Fund,
substr(unpvt.period,9,2) Period,
unpvt.Value
from TEBBALS b
INNER JOIN (select CMPY,SYSREF,ACCT FROM TEBACCT WHERE CMPY = 'RC' and PATH = '0')
d on b.CMPY = d.CMPY and b.SYSREF = d.SYSREF
unpivot(value for period in
(
OPEN_BAL,
PER_BAL_01,
PER_BAL_02,
PER_BAL_03,
PER_BAL_04,
PER_BAL_05,
PER_BAL_06,
PER_BAL_07,
PER_BAL_08,
PER_BAL_09,
PER_BAL_10,
PER_BAL_11,
PER_BAL_12 ) )unpvt
WHERE YY = '2013'
The PER_BAL* fields contain balances at the end of a period and I need it to show the movement between periods, so I need to do a calculation between periods, so (PER_BAL_01 - OPEN_BAL), (PER_BAL_02 - PER_BAL_01) etc.
Any ideas anyone?
Related
I have the following query:
SELECT DISTINCT
CAB.CODPARC,
PAR.RAZAOSOCIAL,
BAI.NOMEBAI,
SUM(VLRNOTA) AS AMOUNT
FROM TGFCAB CAB, TGFPAR PAR, TSIBAI BAI
WHERE CAB.CODPARC = PAR.CODPARC
AND PAR.CODBAI = BAI.CODBAI
AND CAB.TIPMOV = 'V'
AND STATUSNOTA = 'L'
AND PAR.CODCID = 5358
GROUP BY
CAB.CODPARC,
PAR.RAZAOSOCIAL,
BAI.NOMEBAI
Which the result is this. Company names and neighborhood hid for obvious reasons
The query at the moment, for those who don't understand Latin languages, is giving me clients, company name, company neighborhood, and the total value of movements.
in the WHERE clause it is only filtering sales movements of companies from an established city.
But if you notice in the Select statement, the column that is retuning the value that aggregates the total amount of value of sales is a SUM().
My goal is to return only the company that have the maximum value of this column, if its a tie, display both of em.
This is where i'm struggling, cause i can't seem to find a simple solution. I tried to use
WHERE AMOUNT = MAX(AMOUNT)
But as expected it didn't work
You tagged the question with the whole bunch of different databases; do you really use all of them?
Because, "PL/SQL" reads as "Oracle". If that's so, here's one option.
with temp as
-- this is your current query
(select columns,
sum(vrlnota) as amount
from ...
where ...
)
-- query that returns what you asked for
select *
from temp t
where t.amount = (select max(a.amount)
from temp a
);
You should be able to achieve the same without the need for a subquery using window over() function,
WITH T AS (
SELECT
CAB.CODPARC,
PAR.RAZAOSOCIAL,
BAI.NOMEBAI,
SUM(VLRNOTA) AS AMOUNT,
MAX(VLRNOTA) over() AS MAMOUNT
FROM TGFCAB CAB
JOIN TGFPAR PAR ON PAR.CODPARC = CAB.CODPARC
JOIN TSIBAI BAI ON BAI.CODBAI = PAR.CODBAI
WHERE CAB.TIPMOV = 'V'
AND STATUSNOTA = 'L'
AND PAR.CODCID = 5358
GROUP BY CAB.CODPARC, PAR.RAZAOSOCIAL, BAI.NOMEBAI
)
SELECT CODPARC, RAZAOSOCIAL, NOMEBAI, AMOUNT
FROM T
WHERE AMOUNT=MAMOUNT
Note it's usually (always) beneficial to join tables using clear explicit join syntax. This should be fine cross-platform between Oracle & SQL Server.
The table I currently have looks like this:
(data comes from two different tables, 19921231, 19930331)
The table I want to create looks like this (5th column added)
Goal: determine the deposit growth rate at each bank. I.e. Comparing the amount of deposits held at a bank in the previous quarter (e.g. 19921231) to the deposits of the most recent quarter (e.g. 19930331). Then view the increase/decrease as a percentage.
This is the code I have written so far:
select
AL.repdte as `Date`, AL.cert, AL.name, AL.dep as `Deposits`
FROM usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as AL
UNION ALL
select
AL.repdte as `Date`, AL.cert, AL.name, AL.dep as `Deposits`
FROM usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as AL
An answer to this question suggested this code, that works
However, for some reason I getting an output of "NULL"
select al19930331.repdte as `Date`, al19930331.cert, al19930331.name,
al19930331.dep as Deposits_1993,
al19921231.dep as Deposits_1992,
(al19930331.dep - al19921231.dep) / al19921231.dep as grow_rate
from usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as al19930331 left join
usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as al19921231
on al19930331.cert = al19921231.cert and
al19930331.name = al19921231.name and
al19921231.repdte = date_add(al19930331.repdte, interval 1 year);
In an attempt to isolate the "NULL" issue, I reduced the query to it's simplest terms, and was able to eliminate the "NULL" issue.
Now we have deposit columns for both quarters returning what appears to be proper outputs.
Next I removed the last line of code from:
select al19930331.repdte as `Date`, al19930331.cert, al19930331.name,
al19930331.dep as Deposits_1993,
al19921231.dep as Deposits_1992,
(al19930331.dep - al19921231.dep) / al19921231.dep as grow_rate
from usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as al19930331 left join
usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as al19921231
on al19930331.cert = al19921231.cert and
al19930331.name = al19921231.name and
al19921231.repdte = date_add(al19930331.repdte, interval 1 year);
Removing the last line of code worked, sort of. Running the code produces a "division by zero" error. How can one eliminate the division by zero error?
select al19930331.repdte as `Date`, al19930331.cert, al19930331.name,
al19930331.dep as Deposits_1993,
al19921231.dep as Deposits_1992,
(al19930331.dep - al19921231.dep) / al19921231.dep as grow_rate
from usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as al19930331 left join
usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as al19921231
on al19930331.cert = al19921231.cert and
al19930331.name = al19921231.name
You should not be storing this information in different tables. This should all be in the same table using different partitions. But with the date embedded in the middle of the name, I think you need to use an explicit join:
select al19930331.repdte as `Date`, al19930331.cert, al19930331.name,
al19930331.dep as Deposits_1993_0331,
al19921231.dep as Deposits_1992_1231,
(al19930331.dep - al19921231.dep) / al19921231.dep as grow_rate
from usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as al19930331 left join
usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as al19921231
on al19930331.cert = al19921231.cert and
al19921231.repdte = date_add(al19930331.repdte, interval 1 quarter);
This would be simpler with the data in one table.
You can use lag():
select
t.*,
100.0
* (deposits - lag(deposits) over(partition by cert order by depdte))
/ lag(deposits) over(partition by cert order by depdte) as growth_percent
from mytable t
In the following query I am trying to get TotalQty to SUM across both the locations for item 6112040, but so far I have been unable to make this happen. I do need to keep both lines for 6112040 separate in order to capture the different location.
This query feeds into a Jasper ireport using something called Java.Groovy. Despite this, none of the PDFs printed yet have been either stylish or stained brown. Perhaps someone could address that issue as well, but this SUM issue takes priority
I know Gordon Linoff will get on in about an hour so maybe he can help.
DECLARE #receipt INT
SET #receipt = 20
SELECT
ent.WarehouseSku AS WarehouseSku,
ent.PalletId AS [ReceivedPallet],
ISNULL(inv.LocationName,'') AS [ActualLoc],
SUM(ISNULL(inv.Qty,0)) AS [LocationQty],
SUM(ISNULL(inv.Qty,0)) AS [TotalQty],
MAX(CAST(ent.ReceiptLineNumber AS INT)) AS [LineNumber],
MAX(ent.WarehouseLotReference) AS [WarehouseLot],
LEFT(SUM(ent.WeightExpected),7) AS [GrossWeight],
LEFT(SUM(inv.[Weight]),7) AS [NetWeight]
FROM WarehouseReceiptDetail AS det
INNER JOIN WarehouseReceiptDetailEntry AS ent
ON det.ReceiptNumber = ent.ReceiptNumber
AND det.FacilityName = ent.FacilityName
AND det.WarehouseName = ent.WarehouseName
AND det.ReceiptLineNumber = ent.ReceiptLineNumber
LEFT OUTER JOIN Inventory AS inv
ON inv.WarehouseName = det.WarehouseName
AND inv.FacilityName = det.FacilityName
AND inv.WarehouseSku = det.WarehouseSku
AND inv.CustomerLotReference = ent.CustomerLotReference
AND inv.LotReferenceOne = det.ReceiptNumber
AND ISNULL(ent.CaseId,'') = ISNULL(inv.CaseId,'')
WHERE
det.WarehouseName = $Warehouse
AND det.FacilityName = $Facility
AND det.ReceiptNumber = #receipt
GROUP BY
ent.PalletId
, ent.WarehouseSku
, inv.LocationName
, inv.Qty
, inv.LotReferenceOne
ORDER BY ent.WarehouseSku
The lines I need partially coalesced are 4 and 5 in the above return.
Create a second dataset with a subquery and join to that subquery - you can extrapolate from the following to apply to your situation:
First the Subquery:
SELECT
WarehouseSku,
SUM(Qty)
FROM
Inventory
GROUP BY
WarehouseSku
Now apply to your query - insert into the FROM clause:
...
LEFT JOIN (
SELECT
WarehouseSKU,
SUM(Qty)
FROM
Inventory
GROUP BY
WarehouseSKU
) AS TotalQty
ON Warehouse.WarehouseSku = TotalQty.WarehouseSku
Without seeing the actual schema DDL it is hard to know the exact cardinality, but I think this will point you in the right direction.
I'm learning SAP queries.
I want to get all the Measure documents from an equipement.
To do that, I use 3 tables :
EQUI, IMPTT, IMRG
The query works but I have all documents instead I only want to get the last one by Date. But I can't do that. I'm sure that I have to add a custom field, but I have tried but none of them works.
For example, my last code :
select min( IMRG~INVTS ) IMRG~RECDV
from IMRG inner join IMPTT on
IMRG~POINT = IMPTT~POINT into (INVTS, IMRGVAL)
where IMRG~POINT = IMPTT-POINT AND
IMPTT~MPOBJ = EQUI-OBJNR
and IMRG~CANCL = '' group by IMRG~MDOCM IMRG~RECDV.
ENDSELECT.
Thanks for your help.
You will need to get the date from IMRG, and the inverted timestamp field, so the MIN() of this will be the most recent - that looks correct.
However your GROUP BY looks wrong. You should be grouping on the IMPTT~POINT field so that you get one record per measurement point. Note that one Point IMPTT can have many measurements (IMRG), so something like this:
SELECT EQUI-OBJNR, IMPTT~POINT, MIN(IMRG~IMRC_INVTS)
...
GROUP BY EQUI-OBJNR, IMPTT~POINT
If I got you correctly, you are trying to get the freshest measurement of the equipment disregard of measurement point. So you can try this query, which is not so beautiful, but it just works.
SELECT objnr COUNT(*) MIN( invts )
FROM equi AS eq
JOIN imptt AS tt
ON tt~mpobj = eq~objnr
JOIN imrg AS ig
ON ig~point = tt~point
INTO (wa_objnr, count, wa_invts)
WHERE ig~cancl = ''
GROUP BY objnr.
SELECT SINGLE recdv FROM imrg JOIN imptt ON imptt~point = imrg~point INTO wa_imrgval WHERE invts = wa_invts AND imptt~mpobj = wa_objnr.
WRITE: / wa_objnr, count, wa_invts, wa_imrgval.
ENDSELECT.
I am new to SQL so please excuse my lack of knowledge. This is the table i have based on the following statement:
'select S_OPERATION.OPERATIONID, CHANGE_H.SERVICEREQNO, CHANGE_H.UPDATEDDATE
from sunrise.S_OPERATION inner join
CHANGE_H on S_OPERATION.OPERATIONID = CHANGE_H.OPERATIONID
where (S_OPERATION.OPERATIONID = 102005212) OR
(S_OPERATION.OPERATIONID = 102005218) or
(s_operation.operationid = 102005406) or
(s_operation.operationid = 102005401) or
(s_operation.operationid = 102005215)'
enter image description here
I would like to be able to calculate the time difference between events within the same job.
Please note: OperationID=event, Servicereqno=job
My end goal is to calculate the average time taken between each event and export this into a report, but i am having problems getting past the first hurdle.
I have tried the following statement however it does not work:
WITH cteOps AS
(
SELECT
row_number() OVER (PARTITION BY change.servicereqid ORDER BY change.updateddate) seqid,
updateddate,
servicereqid
FROM CHANGE.updateddate, CHANGE.addedby, S_OPERATION.operationid, CHANGE.servicereqid
)
SELECT
DATEDIFF(millisecond, o1.updateddate, o2.updateddate) updateddatediff,
servicereqid
FROM cteOps o1
JOIN cteOps o2 ON o1.seqid=o2.seqid+1 AND o1.servicereqid=o2.servicereqid;
Many thanks in advance.
Your two queries look quite different having different table names, etc. So you'd probably have to adjust my query below to match what you actually have.
You can look into the previous record with LAG. So a query showing all those events with a time difference to the previous one could be:
select
c.updateddate
, c.addedby
, so.operationid
, c.servicereqid
, so.updateddate
, datediff
( millisecond
, lag(so.updateddate) over (partition by c.servicereqid order by so.updateddate)
, so.updateddate
) as updateddatediff
from change c
inner join change_h ch
on c.servicereqid = ch.servicereqno
and ch.operationid in (102005212, 102005218, 102005406, 102005401, 102005215)
inner join s_operation so
on ch.operationid = so.operationid
order by
c.servicereqid,
so.updateddate;
You can build up on this by using it as a derived table (a subquery in a FROM clause).