Can't get PL SQL to divide with two select statements - plsql

I need help getting this code to work. I am trying to use two sql statements to perform a division.
select ((select count(p.issued)
from permit p
where trunc(p.issued) >= trunc(TO_DATE('1/1/2011','MM/DD/YYYY'))
AND trunc(p.issued) <= trunc(TO_DATE('1/31/2011','MM/DD/YYYY')))
/
(select count(p.issued)
from permit p
where (TO_DATE(p.issued) - sysdate) <= 21
and trunc(p.issued) >= trunc(TO_DATE('1/1/2011','MM/DD/YYYY'))
AND trunc(p.issued) <= trunc(TO_DATE('1/31/2011','MM/DD/YYYY')))) as permitPercemt;

You need to add one more SELECT :
SELECT ( (select ....)/(select ... )) as permitPercent FROM DUAL;
UPDATE
So your query will look like:
SELECT (
(
select count(p.issued)
from permit p
where trunc(p.issued) >= trunc(TO_DATE('1/1/2011','MM/DD/YYYY'))
AND trunc(p.issued) <= trunc(TO_DATE('1/31/2011','MM/DD/YYYY'))
) /
(
select count(p.issued)
from permit p
where (TO_DATE(p.issued) - sysdate) <= 21
and trunc(p.issued) >= trunc(TO_DATE('1/1/2011','MM/DD/YYYY'))
AND trunc(p.issued) <= trunc(TO_DATE('1/31/2011','MM/DD/YYYY'))
)
) as permitPercent FROM DUAL;

you don't divide the entire select statement.
you divide two values and return that as a column in the select list.

Related

How to add working days to a date in PLSQL?

I have to add Working Days, to find out Ship_Date, for an Order, depending upon Order_Date and Delivery_Type (Like Standard Delivery, Premium Delivery etc).
So the query should look like
SELECT Order_Id, Delivery_Type, Order_Date, Ship_Date FROM Order_Info
I found SQL for this problem but couldn't understand it and neither and could not refactor it for my needs.
The query is as below
SELECT max(DATE_FIELD_TWO) AS DATE_FIELD_TWO
FROM (
SELECT Date '2018-08-30' + CAST(
CASE
WHEN TO_CHAR(Date '2018-08-30' + Level, 'D', 'NLS_DATE_LANGUAGE=ENGLISH') In
('6', '7') Then 0
ELSE Level
END AS INT) AS DATE_FIELD_TWO,
SUM(CAST(CASE
WHEN TO_CHAR(Date '2018-08-30' + Level, 'D', 'NLS_DATE_LANGUAGE=ENGLISH') In ('6', '7')
THEN 0
ELSE 1
End As Int)) OVER (Order By Level) AS NEXT_DAY
FROM DUAL Connect By Level <= 20 * 1.5)
WHERE NEXT_DAY = 20;

Update only those rows where condition matches criteria based on another table

I have a table 'TABLE_1' with column 'Encoder'. I have another table 'TABLE_2' with columns 'Start', 'End', 'Offset'. I want to adjust or UPDATE the TABLE_1 by adding the 'Offset' value to 'Encoder' with the condition iff 'Encoder' >= 'Start' OR <= 'End'. If the criteria fails then do nothing, leave the original 'Encoder' value. here is my code so far. The problem I have is that it updates the rows fine when the condition is met, but places NULL when it does not.
Update TABLE_1
set encoder =
(
select (TABLE_1.encoder +TABLE_2.Offset) as NewEncoder
from TABLE_2
where
TABLE_1.encoder >= TABLE_2.Start
and
TABLE_1.encoder <= TABLE_2.End
)
I expect the final TABLE_1 to have the rows where the condition is NOT met to be unchanged and only update those that met the criteria. Current code updates those that fail the criteria with NULL
Your UPDATE statement needs a WHERE clause with EXISTS:
Update TABLE_1
set encoder =
(
select (TABLE_1.encoder +TABLE_2.Offset) as NewEncoder
from TABLE_2
where
TABLE_1.encoder >= TABLE_2.Start
and
TABLE_1.encoder <= TABLE_2.End
)
where exists (
select 1 from TABLE_2
where
TABLE_1.encoder >= TABLE_2.Start
and
TABLE_1.encoder <= TABLE_2.End
)
Or use coalesce():
Update TABLE_1
set encoder = coalesce(
(
select (TABLE_1.encoder +TABLE_2.Field3) as NewEncoder
from TABLE_2
where
TABLE_1.encoder >= TABLE_2.Start
and
TABLE_1.encoder <= TABLE_2.End
)
, encoder)

Trying to get unique source, medium, campaign using STRING_AGG function by visitNumber

I am trying to get unique source, medium, campaign using STRING_AGG function partitioning by fullVisitorId and ORDER BY visitNumber.
However, I am getting a lot of repeated fields in Source, medium and campaign using STRING_AGG.
So I thought of using DISTINCT but it doesn't work with STRING_AGG.
Any advice appreciated.
Code:
SELECT
CAST(concat(SUBSTR(date,0,4), '-', SUBSTR(date,5,2),'-',SUBSTR(date,7,2)) as date ) as date,
fullVisitorId,
trafficSource.keyword,
trafficSource.adContent,
STRING_AGG(channelGrouping), ' > ') OVER (PARTITION BY fullVisitorId ORDER BY visitNumber) AS channelPath,
STRING_AGG(trafficSource.medium), ' > ') OVER (PARTITION BY fullVisitorId ORDER BY visitNumber ) AS medium_Path,
STRING_AGG(trafficSource.source), ' > ') OVER (PARTITION BY fullVisitorId ORDER BY visitNumber) AS source_Path,
STRING_AGG(trafficSource.campaign), ' > ') OVER (PARTITION BY fullVisitorId ORDER BY visitNumber) AS campaign_Path
FROM
`tfa-big-query.74006564.ga_sessions_*`,UNNEST(hits) as hit
WHERE _table_suffix BETWEEN '20180801' and '201808015'
The results in the STRING_AGG column (channelgrouping, medium and source is the occurrence of repetitive fields which can be seen as follows:
Actual results:
Organic Search > Organic Search > Organic Search < Other < Other < Direct < Owned < email < email < (none) < (none)
Expected Output:
Organic Search < Other < Direct < Owned < email < (None)
Below is for BigQuery Standard SQL
#standardSQL
CREATE TEMP FUNCTION DeDup(arr ANY TYPE) AS ((
SELECT STRING_AGG(str, ' > ') FROM (
SELECT CONCAT(ANY_VALUE(x), ' (', CAST(COUNT(1) AS STRING), ')') str FROM (
SELECT x, COUNTIF(flag) OVER(ORDER BY OFFSET) grp FROM (
SELECT *,x!=IFNULL(LAG(x) OVER(ORDER BY OFFSET), x) flag FROM UNNEST(arr) x WITH OFFSET
))
GROUP BY grp
)));
SELECT
DATE,
fullVisitorId,
keyword,
adContent,
DeDup(channelPath) AS channelPath,
DeDup(medium_Path) AS medium_Path,
DeDup(source_Path) AS source_Path,
DeDup(campaign_Path) AS campaign_Path
FROM (
SELECT
CAST(CONCAT(SUBSTR(DATE,0,4), '-', SUBSTR(DATE,5,2),'-',SUBSTR(DATE,7,2)) AS DATE ) AS DATE,
fullVisitorId,
trafficSource.keyword,
trafficSource.adContent,
ARRAY_AGG(channelGrouping) OVER(PARTITION BY fullVisitorId ORDER BY visitNumber) AS channelPath,
ARRAY_AGG(trafficSource.medium) OVER(PARTITION BY fullVisitorId ORDER BY visitNumber ) AS medium_Path,
ARRAY_AGG(trafficSource.source) OVER(PARTITION BY fullVisitorId ORDER BY visitNumber) AS source_Path,
ARRAY_AGG(trafficSource.campaign) OVER(PARTITION BY fullVisitorId ORDER BY visitNumber) AS campaign_Path
FROM `tfa-big-query.74006564.ga_sessions_*`,UNNEST(hits) as hit
WHERE _table_suffix BETWEEN '20180801' and '201808015'
)
Above will return something like
Organic Search (3) > Other (2) > Direct (1) > Owned (1) > email (2) > (none) (2)
which is a little extension of your expected result Organic Search < Other < Direct < Owned < email < (None)
I thought STRING_AGG work with DISTINCT
try this sql from bigquery document
SELECT STRING_AGG(DISTINCT fruit, " & ") AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

Case statement duplicating rows - teradata

i have the following query and the problem is in the Case statement. It s being used in a Join condition. for some reason is bringing up both alternatives from the case
here s the code
SELECT C.GREGORIAN_MONTH_ID
,C.BUSINESS_PARTY_ID
,C.TOTAL_MONTO
,C.Capitas_Puntuales
,C.CUIT
,nb_apellido
,nb_oficial_actual
,nb_cne_obe
,nb_nodo
,nb_territorio
,cd_area_negocio
FROM (SELECT gregorian_month_id
,business_party_id
,Case when BUSINESS_PARTY_ID in (88888,200) then '9999999999999' else business_party_ident_num end CUIT
,SUM(amt_accum) Total_Monto
,count(*) Capitas_Puntuales
FROM dbsreg.A127932_PARTY_MAIN_PAYROLL_HISTORY
where gregorian_month_id= 201806
group by 1,2,3
) C
LEFT JOIN
(select NU_CUIT, nb_apellido,nb_oficial_actual, nb_cne_obe, nb_nodo, nb_territorio,cd_area_negocio
,(fh_corte/100 + 190000) gregorian_month_id
from dbsreg.a119527_base_info_gerencial
) G
on C.CUIT = G.NU_CUIT
and (case
when C.gregorian_month_id in (G.gregorian_month_id) then C.gregorian_month_id
else C.gregorian_month_id -1
END) = G.gregorian_month_id
ORDER BY C.BUSINESS_PARTY_ID
anyone can tell what s going on there?
You final query returns C.BUSINESS_PARTY_ID which is not transformed by Case. Your case statement also draws on BUSINESS_PARTY_ID. Did you mean to have C.CUIT instead of C.BUSINESS_PARTY_ID in your outer select statement?
long story short, i moved the case withing to a where statement from table C and added a userdefined value for the gregorian:
SELECT C.GREGORIAN_MONTH_ID
,C.BUSINESS_PARTY_ID
,C.TOTAL_MONTO
,C.Capitas_Puntuales
,C.CUIT
,nb_apellido
,nb_oficial_actual
,nb_cne_obe
,nb_nodo
,nb_territorio
,cd_area_negocio
FROM (SELECT gregorian_month_id
,business_party_id
,Case when BUSINESS_PARTY_ID in (88888,200) then '9999999999999' else business_party_ident_num end CUIT
,SUM(amt_accum) Total_Monto
,count(*) Capitas_Puntuales
FROM dbsreg.A127932_PARTY_MAIN_PAYROLL_HISTORY
where gregorian_month_id= ?FECHA_BASE
group by 1,2,3
) C
LEFT JOIN
(select NU_CUIT, nb_apellido,nb_oficial_actual, nb_cne_obe, nb_nodo, nb_territorio,cd_area_negocio
,(fh_corte/100 + 190000) gregorian_month_id
from dbsreg.a119527_base_info_gerencial
where gregorian_month_id = (Case when ?FECHA_BASE = (gregorian_month_id) then gregorian_month_id else gregorian_month_id-1 end )
) G
on C.CUIT = G.NU_CUIT
ORDER BY C.BUSINESS_PARTY_ID

Using 0 as default count value

I have a query (portion of it) like this below, when my GridView is loaded with this query, those rows that has got no value for IssCount and UsedCount will be blank. How can I set a default 0 value for these columns for such records?
SELECT
CASE
WHEN #SortByTypeCode = 1 THEN ROW_NUMBER() OVER(ORDER BY vt.Code)
WHEN #SortByTypeName = 1 THEN ROW_NUMBER() OVER(ORDER BY vt.Name)
WHEN #SortByTypeIssued = 1 THEN ROW_NUMBER() OVER(ORDER BY count(X.IssCount))
WHEN #SortByTypeUsed = 1 THEN ROW_NUMBER() OVER(ORDER BY count(Y.UsedCount ))
ELSE ROW_NUMBER() OVER(ORDER BY vt.AutoID)
END AS RowNum
,vt.AutoID
,vt.Code
,X.IssCount as Issued
,Y.UsedCount as Used
INTO #tmp_Results --Dont Change This
FROM VoucherType vt
LEFT JOIN (
SELECT VoucherType_AutoID,COUNT(VoucherNo) IssCount
FROM Voucher
WHERE VoidedBy IS NULL AND VoidedOn IS NULL
GROUP BY VoucherType_AutoID
) X ON vt.AutoID = X.VoucherType_AutoID
LEFT JOIN (
SELECT V.VoucherType_AutoID, COUNT(VUsed.AutoID) UsedCount
FROM voucherUsedLog VUsed
INNER JOIN Voucher V ON VUsed.Voucher_AutoID = V.AutoID
WHERE VUsed.VoidedBy IS NULL AND VUsed.VoidedOn IS NULL
GROUP BY V.VoucherType_AutoID
) Y
ON vt.AutoID = Y.VoucherType_AutoID
You can just wrap a COALESCE around X.IssCount and Y.UsedCount to make them 0, like so:
,COALESCE(X.IssCount,0) as Issued
,COALESCE(Y.UsedCount,0) as Used
Try this way..
ISNULL(X.IssCount,0) as Issued
,ISNULL(Y.UsedCount,0) as Used

Resources