Divide the results of two select queries - sql

I have two SQL count queries that on their own work fine, they are:
SELECT count(*) AS TOTAL_PROGRESS_BY_LINE_
FROM dbo.PID_Components_PROCESS_LINES
WHERE ISOGEN_LINE_PROGRESS_ = 'C'
RESULT: TOTAL_PROGRESS_BY_LINE_ = 26
SELECT count(*) AS TOTAL_LINES_BY_PROJECT_
FROM dbo.PID_Components_PROCESS_LINES
WHERE PROJECT_NUMBER_ = 'PJ001234'
RESULT: TOTAL_LINES_BY_PROJECT_ = 130
Now how to do I add to the query to get the percentage of 26/130??
I have a new query to go along with how to get percentages.
Here it is:
SELECT ISOGEN_LINE_PROGRESS_, PROJECT_NUMBER_,
CASE
WHEN ISOGEN_LINE_PROGRESS_ = 'A' THEN 'NOT IN MODEL'
WHEN ISOGEN_LINE_PROGRESS_ = 'B' THEN 'ROUGHED IN'
WHEN ISOGEN_LINE_PROGRESS_ = 'C' THEN 'PARTIAL CHECK'
WHEN ISOGEN_LINE_PROGRESS_ = 'D' THEN 'READY FOR FINAL CHECK'
WHEN ISOGEN_LINE_PROGRESS_ = 'E' THEN '100% COMPLETE'
WHEN ISOGEN_LINE_PROGRESS_ = '0' THEN 'ISSUE FOR CONSTRUCTION'
END AS PROGRESS_PER_LINE_
FROM PID_Components_PROCESS_LINES
WHERE PROJECT_NUMBER_ = 'PJ001234'
ORDER BY ISOGEN_LINE_PROGRESS_
this brings back results below:
ISOGEN_LINE_PROGRESS_ PROJECT_NUMBER_ PROGRESS_PER_LINE_
A PJ001234 NOT IN MODEL
B PJ001234 ROUGHED IN
C PJ001234 PARTIAL CHECK
D PJ001234 READY FOR FINAL CHECK
If I remove the Distinct from my query there are obviously multiple rows for each level of progress. How do I add to the above distinct query to have a column at the end with the rate or percent of each level of progress compared to the overall number of lines?

Select them as a subquery.
By default the result will be an integer because count(*) returns an int. For a decimal result convert to a decimal.
SELECT (
SELECT CONVERT(decimal(9,2),COUNT(*)) AS TOTAL_PROGRESS_BY_LINE_
FROM dbo.PID_Components_PROCESS_LINES
WHERE ISOGEN_LINE_PROGRESS_ = 'C'
) / (
SELECT CONVERT(decimal(9,2),COUNT(*)) AS TOTAL_LINES_BY_PROJECT_
FROM dbo.PID_Components_PROCESS_LINES
WHERE PROJECT_NUMBER_ = 'PJ001234'
)

You may use conditional aggregation and simple division in one query:
select
100.0 *
count(
case when ISOGEN_LINE_PROGRESS_ = 'C'
then 1
end
)
/
nullif(count(
case when PROJECT_NUMBER_ = 'PJ001234'
then 1
end
), 0) as rate_
FROM dbo.PID_Components_PROCESS_LINES
WHERE ISOGEN_LINE_PROGRESS_ = 'C'
or PROJECT_NUMBER_ = 'PJ001234'

DECLARE #firstone INT;
DECLARE #secondone INT;
SELECT #firstone = count(*)
FROM dbo.PID_Components_PROCESS_LINES
WHERE ISOGEN_LINE_PROGRESS_ = 'C';
SELECT #secondone = count(*)
FROM dbo.PID_Components_PROCESS_LINES
WHERE PROJECT_NUMBER_ = 'PJ001234';
SELECT #firstone / #secondone AS resultthing
SELECT #firstone /CAST(#secondone AS DECIMAL (9,2))

You could use a common table expression to get the counts and then select the desired results in one swell foop:
with Counts as (
select
( select Count(*) from Sys.Tables ) as NumberOfTables,
( select Count(*) from Sys.Columns ) as NumberOfColumns
)
select NumberOfTables, NumberOfColumns,
NumberOfColumns / NumberOfTables as ColumnsPerTable,
( 100 * NumberOfColumns ) / NumberOfTables as IntegerPercentColumnsPerTable,
( 100.0 * NumberOfColumns ) / NumberOfTables as NumericPercentColumnsPerTable
from Counts;
I used existing tables since you chose not to supply DDL and sample data. So it goes.

Related

merge CTE query in Oracle

I am looking for an optimized way to merge CTE query as mentioned below. In the below query, the same table is getting hit twice, I am looking for an option to hit this table once and it will only be possible if I remove CTE and put everything into single query. I am using CTE as I need to derive column value and then compare that value..
Query
with cte as
(
select distinct
'UP' search_update_code,
'G' search_prov_entity_type,
prpr.prpr_id search_prov_id,
prpr.mctn_id search_tax_id,
'UP' group_provdata_upd_cd,
'G' group_provdata_entity,
case
when enroll_type = 'AH' THEN 'A'
when enroll_type = 'VP' THEN 'A'
when enroll_type = 'CK' THEN ' '
end group_provdata_clm_eft_pay_ind <-- deriving values here
from
fsg_prcb_pe_enroll_stream prcb
inner join
cmc_prpr_prov prpr on prpr.mctn_id = prcb.prov_tin_number <-- 1st hit
where
prpr.prpr_entity ='G'
and prcb.prov_tin_number = ?
and prcb.error_flag is null
)
select distinct
cte.*
from cte
inner join cmc_prpr_prov prpr on cte.search_prov_id = prpr.prpr_id <-- 2nd hit
where cte.group_provdata_clm_eft_pay_ind <> prpr.prpr_cl_eft_ind <--- comparing derived values here
and prpr_term_dt >= systimestamp
You can rewrite your query like below:
with cte as
(
select distinct
'UP' search_update_code,
'G' search_prov_entity_type,
prpr.prpr_id search_prov_id,
prpr.mctn_id search_tax_id,
'UP' group_provdata_upd_cd,
'G' group_provdata_entity,
case
when enroll_type = 'AH' THEN 'A'
when enroll_type = 'VP' THEN 'A'
when enroll_type = 'CK' THEN ' '
end group_provdata_clm_eft_pay_ind, <-- deriving values here
prpr.prpr_cl_eft_ind prpr_cl_eft_ind_2,
prpr_term_dt
from
fsg_prcb_pe_enroll_stream prcb
inner join
cmc_prpr_prov prpr on prpr.mctn_id = prcb.prov_tin_number <-- 1st hit
where
prpr.prpr_entity ='G'
and prcb.prov_tin_number = ?
and prcb.error_flag is null
)
select distinct
cte.*
from cte
where group_provdata_clm_eft_pay_ind <> prpr_cl_eft_ind_2 <--- comparing derived values here
and prpr_term_dt >= systimestamp

how to use case with group by?

the query works well but when iam adding group by it gives me [Error] ORA-01427 here is the main query
SELECT DISTINCT Contract_number,
area_number,
area_name,
ADVANCE_PAY,
Postponed_Amount,
extract_number,
total
FROM (SELECT xxr.Contract_num Contract_number,
xxr.p_area_no area_number,
xxr.p_area_name area_name,
xxr.ADVANCE_PAY ADVANCE_PAY,
xxr.DEFERRED_BOOST Postponed_Amount,
xxr.release_num extract_number,
and here is the case statement :
(SELECT DISTINCT
CASE
WHEN :p_item_code IS NOT NULL
THEN
TOTAL_AMOUNT
WHEN :p_item_code IS NULL
THEN
( (SELECT NVL (SUM (TOTAL_AMOUNT), 0)
FROM XXEXTRACT.XXNATGAS_REALSES_LINES
WHERE XXEXTRACT.XXNATGAS_REALSES.release_id =
XXEXTRACT.XXNATGAS_REALSES_LINES.release_id))
ELSE
NULL
END
FROM XXEXTRACT.XXNATGAS_REALSES_LINES xxrl,
XXEXTRACT.XXNATGAS_REALSES
WHERE 1 = 1
AND xxrl.release_id =
XXEXTRACT.XXNATGAS_REALSES.release_id)
AS total
and here is the from part :
FROM XXEXTRACT.XXNATGAS_REALSES_LINES xxrl,
XXEXTRACT.XXNATGAS_REALSES xxr
WHERE 1 = 1
AND xxrl.release_id = xxr.release_id
AND xxr.release_date >= NVL (:p_date_from, xxr.release_date)
AND xxr.release_date <= NVL (:p_date_to, xxr.release_date)
AND xxr.Contract_num = NVL (:p_cont_num, xxr.Contract_num)
AND xxr.vendor_id = NVL (:p_ven_id, xxr.vendor_id)
AND xxr.vendor_site_id = NVL (:p_site_id, xxr.vendor_site_id)
)
and here is the group by :
GROUP BY Contract_number,
area_number,
area_name,
ADVANCE_PAY,
Postponed_Amount,
extract_number,
total;
these is the full query so please any help
For sure I couldn't understand very well your query. You could improve your post for next time.
As answer, I think you should encapsulate your select statment and group by using your select as subquery. It is not the best approach but it may works fine.
select *
from (
select distinct Contract_number
,area_number
,area_name
,ADVANCE_PAY
,Postponed_Amount
,extract_number
,total
from (
select xxr.Contract_num Contract_number
,xxr.p_area_no area_number
,xxr.p_area_name area_name
,xxr.ADVANCE_PAY ADVANCE_PAY
,xxr.DEFERRED_BOOST Postponed_Amount
,xxr.release_num extract_number
,(
select distinct case
when :p_item_code is not null
then TOTAL_AMOUNT
when :p_item_code is null
then (
(
select NVL(SUM(TOTAL_AMOUNT), 0)
from XXEXTRACT.XXNATGAS_REALSES_LINES
where XXEXTRACT.XXNATGAS_REALSES.release_id = XXEXTRACT.XXNATGAS_REALSES_LINES.release_id
)
)
else null
end
from XXEXTRACT.XXNATGAS_REALSES_LINES xxrl
,XXEXTRACT.XXNATGAS_REALSES
where 1 = 1
and xxrl.release_id = XXEXTRACT.XXNATGAS_REALSES.release_id
) as total
from XXEXTRACT.XXNATGAS_REALSES_LINES xxrl
,XXEXTRACT.XXNATGAS_REALSES xxr
where 1 = 1
and xxrl.release_id = xxr.release_id
and xxr.release_date >= NVL(:p_date_from, xxr.release_date)
and xxr.release_date <= NVL(:p_date_to, xxr.release_date)
and xxr.Contract_num = NVL(:p_cont_num, xxr.Contract_num)
and xxr.vendor_id = NVL(:p_ven_id, xxr.vendor_id)
and xxr.vendor_site_id = NVL(:p_site_id, xxr.vendor_site_id)
)
) TBL1
group by TBL1.Contract_number
,TBL1.area_number
,TBL1.area_name
,TBL1.ADVANCE_PAY
,TBL1.Postponed_Amount
,TBL1.extract_number
,TBL1.total;

Postgres Aggregating conditional sum

I am trying to sum-aggregate conditional products for total weight of an order (I hope that makes sense). I get error:
ERROR: aggregate function calls cannot be nested
LINE 6: , SUM ( CASE WHEN pc.type = 'TEES' THEN (SUM (opd.qt...
This is query excerpt:
SELECT DISTINCT
o.work_order_number dn
, SUM(opd.qty) units
, SUM (CASE WHEN pc.type = 'TEES' THEN (SUM (opd.qty) * .75)
WHEN pc.type = 'JERSEYS' THEN (SUM (opd.qty) * 1.5)
END) AS weight
Try:
SELECT o.work_order_number dn
, SUM(opd.qty) units
, SUM ( opd.qty * CASE pc.type
WHEN 'TEES' THEN 0.75
WHEN 'JERSEYS' THEN 1.5
END ) AS weight
FROM ...
GROUP BY o.work_order_number
Well what you can do is nest your select statement E.g
select sum(weight),sum(etc)
from (
SELECT DISTINCT o.work_order_number dn
, (opd.qty) units
, ( CASE WHEN pc.type = 'TEES' THEN ((opd.qty) * .75)
WHEN pc.type = 'JERSEYS' THEN ((opd.qty) * 1.5) END) AS weight)
).
So first select statement handles your case statement and second select statement sums up your fields.

Firebird: sum of the multiplication of two fields within a select statement

Basically what I need is to get the sum of the multiplication of two fields.
For example: SUM ((field_1 or field_2) * field_3)
But field_1 or field_2 are selected based on the value of a fourth field, field_4
My table:
field_1: Float
field_2: Float
field_3: Float
field_4: Char
In short, what i need is something like this:
SELECT
...
IF field_4 = 'K'
THEN
SUM( field_1 * field_3 )
ELSE
SUM( field_2 * field_3 )
I tried with IF and CASE statements, but i can't make it work.
Here my real query:
SELECT
D.id,
D.name,
SUM(CASE WHEN D.sale_unity = 'K'
THEN (D.cost_price * CI.quantity_k)
ELSE (D.cost_price * CI.quantity_u) ) AS total_cost,
SUM(CASE WHEN D.sale_unity = 'K'
THEN (D.sale_price * CI.quantity_k)
ELSE (D.sale_price * CI.quantity_u) ) AS net
FROM DETAIL D
INNER JOIN VOUCHER AS V ON V.id = D.voucher_id
WHERE V.client_id = 97 AND V.date BETWEEN '06/01/2012' AND '07/01/2012'
GROUP BY D.id, D.name
I think that what is wrong on your query is that your CASE statement is missing the END. Try this:
SELECT
D.id,
D.name,
SUM(CASE WHEN D.sale_unity = 'K'
THEN (D.cost_price * CI.quantity_k)
ELSE (D.cost_price * CI.quantity_u) END ) AS total_cost,
SUM(CASE WHEN D.sale_unity = 'K'
THEN (D.sale_price * CI.quantity_k)
ELSE (D.sale_price * CI.quantity_u) END ) AS net
FROM DETAIL D
INNER JOIN VOUCHER AS V ON V.id = D.voucher_id
WHERE V.client_id = 97 AND V.date BETWEEN '06/01/2012' AND '07/01/2012'
GROUP BY D.id, D.name

where clause did not work with WITH

where clause did not work with WITH when i wrote where Prse ='h' it shows me an error 'Invalid column'
;with cT(FLDID ,FLD10 ,FLD610)
as
(
select * from Table556
inner join Table555 on table555.FLD9=FLD318
where FLD610=150
)
select case when fld609 <=12 then 'h' else 's' end as Prse,* from cT
where Prse ='h'
The with has nothing to do with it. You're only introducing Prse in the final SELECT clause - and you can't reference such columns from the WHERE clause (since WHERE logically runs before SELECT).
Did you want:
;with cT(Prse, FLDID ,FLD10 ,FLD610)
as
(
select case when fld609 <=12 then 'h' else 's' end as Prse, * from Table556
inner join Table555 on table555.FLD9=FLD318
where FLD610=150
)
select * from cT
where Prse ='h'
Try this one -
;WITH cte AS
(
SELECT
FLDID
, FLD10
, FLD610
, Prse =
CASE WHEN FLD609 <= 12
THEN 'h'
ELSE 's'
END
FROM dbo.Table556 t
JOIN dbo.Table555 t2 ON t2.FLD9 = t.FLD318
WHERE FLD610 = 150
)
SELECT *
FROM cte
WHERE Prse = 'h'