Oracle SQL Summary report - sql

I'm a new junior developer using reporting as a tool to learn the database structure, we have a reporting tool called Cyberquery to produce these reports but i like to mirror what i do in that in SQL Developer so i can learn both.
Unfortunately i have hit a wall with this problem...
I am trying to produce a summary report of product sales over 24 months, broken down by each month like the table below.
| 2014/10 | 2014/11 | 2014/12 | Total
item no | description | qty | value | qty | value | qty | value | qty | value
a item a 4 20 1 5 2 10 7 35
b item b 1 10 2 20 3 30 6 60
Unfortunately i have not been able to format the query to display the results like this. The sql i have been using goes like this:
select * from(
select i.item_no, i.description, sl.line_value, sl.line_qty, sh.invoice_date
from sales_line sl
join sales_header sh on sh.invoice_no = sl.invoice_no
join item i on i.item_no = sl.item_no
where sh.invoice_date >= add_months((last_day(sysdate)+1),-24)
)
So i have tried a few different ways, originally i thought it would be a case of just using group by but after i couldn't get that to work i had a look at using the pivot function and couldn't get that to work either.
Is this possible in SQL?
Kind Regards,
Richard

Related

Dividing sum results

I'm really sorry as this was probably answered before, but I couldn't find something that solved the problem.
In this case, I'm trying to get the result of dividing two sums in the same column.
| Id | month | budget | sales |
| -- | ----- | ------ | ----- |
| 1 | jan | 1000 | 800 |
| 2 | jan | 1000 | 850 |
| 1 | feb | 1200 | 800 |
| 2 | feb | 1100 | 850 |
What i want is to get the % of completition for each id and month (example: get 0,8 or 80% in a fifth column for id 1 in jan)
I have something like
sel
id,
month,
sum (daily_budget) as budget,
sum (daily_sales) as sales,
budget/sales over (partition by 1,2) as efectivenes
from sales
group by 1,2
I know im doing this wrong but I'm kinda new with sql and cant find the way :|
Thanks!
This should do it
CAST(ROUND(SUM(daily_sales) * 100.00 / SUM(daily_budget), 1) AS DECIMAL(5,2)) AS Effectiveness
I'm new at SQL too but maybe I can help. Try this?
sel
id,
month,
sum (daily_budget) as budget,
sum (daily_sales) as sales,
(sum(daily_budget)/sum(daily_sales)) over (partition by id) as efectivenes
from sales
group by id
If you want to ALTER your table so that it contains a fifth column where the result of budget/sales is automatically calculated, all you need to do this add the formula to this auto-generated column. The example I am about to show is based on MySQL.
Open MySQL
Find the table you wish to modify in the Navigator Pane, right-click on it and select "Alter Table"
Add a new row to your table. Make sure you select NN (Not Null) and G (Generated Column) check boxes
In the Default/Expression column, simply enter the expression budget / sales.
Once you run your next query, you should see your column generated and populated with the calculated results. If you simply want the SQL statement to do the same from the console, it will be something like this: ALTER table YOUR_TABLE_NAME add result FLOAT as (budget / sales);

Access SQL - INSERT INTO using a Union query with errors

I have a table that contains various performance metric values. I have a query (subQryKPI) built on the fly, that displays these metrics horizontally like so:
| EmployeeID | Sales | Calls | Hours |
--------------------------------------
| 22567 | 4 | 10 | 5 |
| 98321 | 8 | 12 | 6 |
| 24680 | 0 | 0 | 3 |
I have another table that contains the formulas for various KPIs:
| KPI | Formula |
--------------------------------------
| Sales per Call | [Sales] / [Calls] |
| Calls per Hour | [Calls] / [Hours] |
Lastly, I have some VBA code that builds an SQL query to calculate the KPI scores for each person and insert them into a table (tblKPIdata).
Until now the query was built to calculate 1 KPI at a time like this:
INSERT INTO
tblKPIdata
SELECT
EmployeeID,
"Sales per Call" as KPIname,
[Sales]/[Calls] AS KpiScore
FROM
SubQryKPI
This works fine and even works if the Select query includes Div/0 errors (e.g EmployeeID 24680 above); it just appears to filter the errors out which is fine as that suits my needs.
The problem that I am having is that I am trying to update the code to calculate multiple KPIs at the same time. I have tried to do this using a Union query like so:
INSERT INTO
tblKPIdata
SELECT * FROM (
SELECT
EmployeeID,
"Sales per Call" as KPIname,
[Sales]/[Calls] AS KpiScore
FROM
SubQryKPI
UNION ALL
SELECT
EmployeeID,
"Calls per Hour" as KPIname,
[Calls]/[Hours] AS KpiScore
FROM
SubQryKPI)
But it appears that if there is a Div/0 error in the Union query it cannot be inserted into another table. (I cannot use the old trick of IIf(divisor = 0,0... as I never know what the divisor is going to be.
Does anyone know why errors can't be ignored in the same way when they are part of a Union query and if there is any way around this?
You could restructure your query using the splt function to identify the dividend and control the error.
Dim LString as a string
Dim LArray () as a string
LString = "[Calls] / [Hours]"
LArray = Split (LString, "/")
MsgBox LArray (0) // [Calls]
MsgBox LArray (1) // [Hours] <------ apply IIF control

Google Big Query : Window Function Row Wise Cumulative Sum Across Columns

I am looking to calculate cumulative sum across columns in Google Big Query.
Assume there are five columns (NAME,A,B,C,D) with two rows of integers, for example:
NAME | A | B | C | D
----------------------
Bob | 1 | 2 | 3 | 4
Carl | 5 | 6 | 7 | 8
I am looking for a windowing function or UDF to calculate the cumulative sum across rows to generate this output:
NAME | A | B | C | D
-------------------------
Bob | 1 | 3 | 6 | 10
Carl | 5 | 11 | 18 | 27
Any thoughts or suggestions greatly appreciated!
I think, there are number of reasonable workarounds for your requirements mostly in the area of designing better your table. All really depends on how you input your data and most importantly how than you consume it
Still, if to stay with presented requirements - Below is not exactly what you expect in your question as an output, but might be usefull as an example:
SELECT name, GROUP_CONCAT(STRING(cum)) AS all FROM (
SELECT name,
SUM(INTEGER(num))
OVER(PARTITION BY name
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cum
FROM (
SELECT name, SPLIT(all) AS num FROM (
SELECT name,
CONCAT(STRING(a),',',STRING(b),',',STRING(c),',',STRING(d)) AS all
FROM yourtable
)
)
)
GROUP BY name
Output is:
name all
Bob 1,3,6,10
Carl 5,11,18,26
Depends on how you than consume this data - it still can work for you
Note, not you avoiding now writing something like col1 + col2 + .. + col89 + col90 - but still need to explicitelly mention each column just ones.
in case if you have "luxury" of implementing your requirements outside of GBQ UI, but rather in some Client- you can use BigQuery API to programatically aquire table schema and build on fly your logic/query and than execute it
Take a look at below APIs to start with:
To get table schema - https://cloud.google.com/bigquery/docs/reference/v2/tables/get
To issue query job - https://cloud.google.com/bigquery/docs/reference/v2/jobs/insert
There's no need for a UDF:
SELECT name, a, a+b, a+b+c, a+b+c+d
FROM tab

SQL select only highest date

For a project I want to generate a price list.
I want to get only the latest prices from each supplier for each article.
There are just those two tables.
Table articles
ARTNR | TXT | ACTIVE | SUPPLIER
------------------------------------------
10 | APPLE | Y | 10
20 | ORANGE | Y | 10
30 | KEYBOARD | N | 20
40 | ORANGE | Y | 20
50 | BANANA | Y | 10
60 | CHERRY | Y | 10
Table prices
ARTNR | PRCGRP | PRCDAT | PRICE
--------------------------------------
10 | 10 | 01-Aug-10 | 2.1
10 | 10 | 05-Aug-11 | 2.2
10 | 10 | 21-Aug-12 | 2.5
20 | 0 | 01-Aug-10 | 2.1
20 | 10 | 09-Aug-12 | 2.3
10 | 10 | 14-Aug-13 | 2.7
This is what I have so far:
SELECT
ARTICLES.[ARTNR], ARTICLES.[TXT], ARTICLES.[ACTIVE], ARTICLES.[SUPPLIER], PRICES.PRCGRP, PRICES.PRCDAT, PRICES.PRICE
FROM
ARTICLES INNER JOIN PRICES ON ARTICLES.ARTNR = PRICES.ARTNR
WHERE
(
(ARTICLES.[ACTIVE]="Y") AND
(ARTICLES.[SUPPLIER]=10) AND
(PRICES.PRCGRP=0) AND
(PRICES.PRCDAT=(SELECT MAX(PRCDAT) FROM PRICES as art WHERE art.ARTNR = PRICES.artnr) )
)
ORDER BY ARTICLES.ARTNR
;
It is okay to choose just one supplier each time, but I want the max price.
The problem is:
Lots of articles do not show up with the query above,
but I cannot figure out what is wrong.
I can see that they should be in the resultset when I leave out the subselect on max prcdat.
What is wrong?
Your subquery to get the latest price does not take the other conditions into account, that is when you're getting the latest price, you may get a price in another price group or that is not active. When you join that against the filtered list that has no inactive prices and only prices in a single price group, you get no hits that exist in both.
Either you need to duplicate or - better - move your conditions inside the subquery to get the best price under the conditions. I can't test against access, but something like this should be possible if the SQL is not too limited;
SELECT a.artnr, a.txt, a.active, a.supplier, p.prcgrp, p.prcdat, p.price
FROM articles a INNER JOIN prices p ON a.ARTNR = p.ARTNR
JOIN (
SELECT a.artnr, MAX(p.prcdat) prcdat
FROM articles a JOIN prices p ON a.artnr = p.artnr
WHERE a.active='Y' AND a.supplier=10 AND p.prcgrp=10
GROUP BY a.artnr) z
ON a.artnr = z.artnr AND p.prcdat = z.prcdat
ORDER BY a.ARTNR
If the SQL support in access won't allow a join with a subquery, you can just move the conditions inside your existing subquery, something like;
SELECT a.artnr, a.txt, a.active, a.supplier, p.prcgrp, p.prcdat, p.price
FROM articles a INNER JOIN prices p ON a.ARTNR = p.ARTNR
WHERE p.prcdat = (
SELECT MAX(p2.prcdat)
FROM articles a2 JOIN prices p2 ON a2.artnr = p2.artnr
WHERE a.artnr = a2.artnr AND a2.active='Y' AND a2.supplier=10 AND p2.prcgrp=10
)
ORDER BY a.ARTNR;
Note that due to limitations in identifying a unique price (no primary key in prices), the queries may give duplicates if several prices for the same article have the same prcdat. If that's a problem, you'll probably need to duplicate your conditions outside the subquery too.

Total with select query

Consider the following data:
Insurance_Comp | 1To30DaysAgeing | 31To60DaysAgeing | 61To90DaysAgeing | TotalVehicles
=============================================================================
ABC | 30 | 5 | 20 | 55
XYZ | 10 | 35 | 5 | 50
I am calculating the number of vehicles aged for particular group after a stock# is assigned to that vehicle. The number of vehicles for a group (ex. 1 to 30 Days Ageing) is calculated using a complex query. I have written SP to get this result. What I want is to calculate the total of vehicles while executing the same select query. For simplification I have created functions in SQL to get number of vehicles for each group.
Right now I m using the query like this ...
Select Ins_Comp, dbo.fn_1To30Ageing(...), dbo.fn_31To60Ageing(...), dbo.fn_61To90Ageing(...) from Table Where ....
I am calculating the total using RowDataBound event of GridView in ASP.NET with C#. Is there any way to calculate the total within query itself? By the way I don't want total as dbo.fn_1To30Ageing(...)+ dbo.fn_31To60Ageing(...) + dbo.fn_61To90Ageing, because that requires double processing time.
I'm not familir with ASP.NET, but if it is only SQL aspect, you can certainly use sub-query:
SELECT A,B,C,SUM(A+B+C) FROM (
Select Ins_Comp, dbo.fn_1To30Ageing(...) AS A, dbo.fn_31To60Ageing(...) AS B, dbo.fn_61To90Ageing(...) AS C from Table Where ....
) TEMP