How to Substract using Posgres within same column - sql

I need to subtract the raw data using same column.
The formula is
(provisioned port-shelf x 16 ) - (provisioned summary - provisioned RCMM).
Anyone have idea so that i can improve my query.

Assuming I'm understanding your question correctly, given your sample data, your expected result should be 16 for A. Assuming so, here's one option using conditional aggregation:
select ne,
max(case when type = 'port-shelf' then 16 * provisioned else 0 end) -
max(case when type = 'summary' then provisioned else 0 end) -
max(case when type = 'rcmm' then provisioned else 0 end) as free_slot,
insert_date
from yourtable
group by ne, insert_date

Related

How to get output in sql two rates into two column in same table

Please help on this. Sometimes my title maybe wrong. Actually i'm unable to explain the problem in word. See below images. Image 1 is db table structure. Image 2 is what I expect result.
I used mentioned query and got result as below image. Also I need to remove 'NULL's and same URGENT_LEVEL values in one row. How i do that? Using ms-sql server.
select TRACKING_NUMBER,URGENT_LEVEL,
case when FROM_KM = '0' then Charge end as 'Under1km' ,
case when FROM_KM='1' then Charge end as '1-100KM'
from my_table
where TRACKING_NUMBER = 'TEST001'
After query
You can use conditional aggregation:
select tracking_number, urgent_level,
sum(case when to_km - from_km <= 1 then charge else 0 end) as charge_under_1,
sum(case when to_km - from_km > 1 and to_km - from_km <= 100 then charge else 0 end) as charge_1_100
from t
group by tracking_number, urgent_level;
I don't know which database you are using, but you need to use group by clause, and something similar to case expression (in oracle) as below :
select TRACKING_NUMBER
, URGENT_LEVEL
, max(case when FROM_KM = 0 and TO_KM = 1 then CHARGE end) as "UNDER 1KM"
, max(case when FROM_KM = 1 and TO_KM = 100 then CHARGE end) as "1-100KM"
from your_table
where TRACKING_NUMBER = 'TEST001'
group by TRACKING_NUMBER, URGENT_LEVEL
order by "UNDER 1KM"
;

Pivot rows into unknown number of columns

I have an access to Oracle server. There is a table on the Oracle server called Transactions which contains the following data:
I don't known the number of values, so we need to implement dynamic sql in Oracle.
I need to pivot that data so the results are:
Any suggestions?
You can use conditional aggregation:
select subno,
sum(case when offer = 'offer1' then 1 else 0 end) as offer1,
sum(case when offer = 'offer2' then 1 else 0 end) as offer2,
sum(case when offer = 'offer3' then 1 else 0 end) as offer3
from t
group by subno;

SQL transpose multi column table without aggregation

I have a dataset in the format;
And need to it in the format;
I have had various attempts at pivot and unpivot for the last week but am not a real programmer and know when to ask a grownup for help.
The database is running on MSSQL 2012 and the dataset will consist of 14 Mode_Antibiotics, ModeQualifier and ModeMIC entries per ClinicalTrialID with a total of approximately 3000 ClinicalTrialIDs.
It's going to be hard to do it in pure SQL dynamically. If I new T-SQL, I would write a table function returning the required dataset. However, in a pure ANSI SQL, since you don't have that many columns, you could use something like this:
SELECT
ClinicalTrialID,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_Antibiotic
END) Antibiotic1,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_Qualifier
END) Qualifier1,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_MIC
END) MIC1,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_Antibiotic
END) Antibiotic2,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_Qualifier
END) Qualifier2,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_MIC
END) MIC2,
-- repeat 12 times with the remaining antibiotics
FROM t
GROUP BY ClinicalTrialID;
Hope that helps.

Grouping multiple column operations in 1 table scan

I need to translate SAS code (PROC SQL) to (postgres) SQL, especially the calculated keyword in SAS that allow a variable defined in the query to be re-used directly in the same query for another variable computation:
SELECT
id,
sum( case
when (sales > 0) then 1
when (sales = 0) then 0
else -1
end) as pre_freq,
(case
when calculated pre_freq > 0 then calculated pre_freq
else 1
end) as freq
FROM my_table
GROUP BY id
This is not possible (AFAIK) in SQL, so I need to break down each step of the computation.
I was wondering what was the best option, knowing that, from my understanding, it is better to have more computations and fewer table scans, i.e. make as much as computation during a scan, instead of multiple table scans with a small computation steps.
In this particular exemple I could use:
SELECT
id
, greatest(1, sum( case
when (sales > 0) then 1
when (sales = 0) then 0
else -1
end) as freq
FROM
my_table
GROUP BY id
or:
SELECT
id
, (case when sum(case
when (sales > 0) then 1
when (sales < 0) then -1
else 0
end) > 0 then sum(case
when (sales > 0) then 1
when (sales < 0) then -1
else 0
end) else 1 end) as freq
FROM
my_table
GROUP BY id
... which is starting to be hard to read...
Is there anyway to define a variable for a snippet of SQL code that will be repeated?
More generally speaking that this illustration, was is the best (most efficient) approach?
calculated is a nice feature of proc sql. However, you cannot re-use aliases in databases in general (this is not a Postgres-specific limitation). A simple method is to use a subquery or CTE:
select id, pre_freq,
(case when pre_freq > 0 then pre_freq
else 1
end) as freq
from (select id,
sum(case when (sales > 0) then 1
when (sales = 0) then 0
else -1
end) as pre_freq,
from my_table t
group by id
) t;
However, the simplest solution is to use sign():
select id, sum(sign(sales)) as pre_freq,
greatest(sum(sign(sales)), 1) as freq
from my_table t
group by id;
Note: This is slightly different. It basically ignores NULL values. If you really need to treat NULL as -1, then use coalesce().

Conditional SUM with SELECT statement

I like to sum values in a table based on a condition taken from the same table called. The structure of the table as per below. The table is called Data
Data
Type Value
1 5
1 10
1 15
1 25
1 15
1 20
1 5
2 10
3 5
If the Value of Type 2 is larger than the Value of Type 3 then I like to subtract the Value of Type 2 from the sum of all the Values in the table. I'm not sure how to write the IF statements using Values looked up in the table. I have tried below but it doesn't work.
SELECT SUM(Value)-IF(SELECT Value FROM Data WHERE Type=2>SELECT Value
FROM Data WHERE Type=3 THEN SELECT Value FROM Data
WHERE Type=2 ELSE SELECT Value FROM Data WHERE Type=3) FROM Data
or
SELECT SUM(d.Value)-IIF(a.type2>b.type3, a.type2, b.type3)
FROM Data d, (SELECT Value AS type2 FROM Data WHERE Type=2) a,
(SELECT Value AS type3 FROM Data WHERE Type=3) b
If I follow your logic correctly, then this would seem to do what you want:
select d.value - (case when d2.value > d3.value then d2.value else 0 end)
from data d cross join
(select value from data where type = 2) d2 cross join
(select value from data where type = 3) d3 ;
EDIT:
If you want just one number, then use conditional aggregation:
select sum(value) -
(case when sum(case when type = 2 then value else 0 end) >
sum(case when type = 3 then value else 0 end)
then sum(case when type = 2 then value else 0 end)
else 0
end)
from data;
Thanks for pointing me in the right direction. This is what I came up with in the end. It is a little bit different to the reply above since I'm using MS Access
SELECT SUM(Value)-IIf(SUM(IIf(Type=2, Value, 0)>SUM(IIf(Type=3, Value, 0), SUM(IIf(Type=2, Value, 0), SUM(IIf(Type=3, Value, 0) FROM Data
It is them same as the second suggestion above but adapted to MS Access SQL.