I have a query in Oracle SQL Developer to grab data from a raw table (all the data on the raw table are varchars) where I need to "clean" the data when I select it. Have to use a CASE statement to get the store number because sometimes that data isn't in the STORENBR column but can be found in a substring of another column -
SELECT
CASE WHEN m.STORENBR = '0' AND (SUBSTR(m.SENDING_QMGR, 1, 5) = 'PDPOS')
THEN TO_NUMBER((SUBSTR(m.SENDING_QMGR, 8, 4)))
WHEN m.STORENBR = '0' AND (SUBSTR(m.SENDING_QMGR, 1, 8) = 'PROD_POS')
THEN TO_NUMBER((SUBSTR(m.SENDING_QMGR, 9, 4)))
ELSE TO_NUMBER(NVL(m.STORENBR, '0'))
END AS STORENBR,
TO_NUMBER(NVL(m.CONTROLNBR,'0')) AS CONTROLNBR,
TO_NUMBER(NVL(m.LINENBR,'0')) AS LINENBR,
TO_DATE(m.TRANDATE,'YYYY-MM-DD') AS TRANDATE,
TO_NUMBER(NVL(m.NUMMISPRINTED,'0.00'),'99.99') AS NUMMISPRINTED
FROM MISPRINTS_RAW m
WHERE TO_DATE(m.TRANDATE,'YYYY-MM-DD') = '15-MAR-21'
ORDER BY m.STORENBR;
Now I need to also pull an account number from another table (TRANSACTIONS t - not a raw table, so I don't need any CASE or TO_NUMBER to pull data) but I need to join that table on STORENBR, CONTROLNBR, and LINENBR. So how do I use that CASE statement as part of the join to JOIN m.STORENBR on t.STORENBR?
Even if I am not sure about the data structure the following statement should be helpful.
The table with the raw data is "converted" in a subselect, so that a normal join is possible.
SELECT *
FROM (SELECT CASE
WHEN m.storenbr = '0'
AND ( Substr(m.sending_qmgr, 1, 5) = 'PDPOS' ) THEN
To_number(
( Substr(m.sending_qmgr, 8, 4) ))
WHEN m.storenbr = '0'
AND ( Substr(m.sending_qmgr, 1, 8) = 'PROD_POS' ) THEN
To_number(( Substr(m.sending_qmgr, 9, 4) ))
ELSE To_number(Nvl(m.storenbr, '0'))
END AS STORENBR,
To_number(Nvl(m.controlnbr, '0')) AS CONTROLNBR,
To_number(Nvl(m.linenbr, '0')) AS LINENBR,
To_date(m.trandate, 'YYYY-MM-DD') AS TRANDATE,
To_number(Nvl(m.nummisprinted, '0.00'), '99.99') AS NUMMISPRINTED
FROM misprints_raw m) m1,
TRANSACTION t
WHERE t.storenbr = m1.storenbr
AND t.controlnbr = m1.controlnbr
AND t.linenbr = m1.linenbr
AND m1.trandate = DATE '2021-03-15'
ORDER BY m1.storenbr;
Related
I have the following insert query:
INSERT INTO dmf_val_error_log
WITH min_loc_trait AS
(
SELECT h.loc_trait,
h.description loc_trait_desc, -- To compare with this brand division (last 3 CHARS of div_name)
d.STORE,
--- MIN(d.loc_trait) OVER (PARTITION BY d.STORE) store_min_loc_trait,
COUNT(*) OVER (PARTITION BY d.STORE) store_cnt
FROM mig_loc_traits h,
mig_loc_traits_matrix d
WHERE h.loc_trait = d.loc_trait
),
this_brand_loc_trait AS
(
SELECT mlt.loc_trait,
regexp_substr(mlt.loc_trait_desc, '[^_]+', 1, 2) brand,
mlt.store
FROM min_loc_trait mlt,
mig_division d
WHERE d.div_name LIKE regexp_substr(mlt.loc_trait_desc, '[^_]+', 1, 2) || '_' || '%'
GROUP BY mlt.loc_trait,
regexp_substr(mlt.loc_trait_desc, '[^_]+', 1, 2),
mlt.store
),
valid_brand_loc_trait AS
(
SELECT d.loc_trait,
regexp_substr(d.loc_trait_desc, '[^_]+', 1, 2) brand,
d.store
FROM min_loc_trait d
WHERE regexp_substr(d.loc_trait_desc, '[^_]+', 1, 2) = 'DEB'
AND d.store_cnt - 1 = 1
AND EXISTS (SELECT 1
FROM this_brand_loc_trait bvs
WHERE bvs.STORE = d.store)
GROUP BY d.loc_trait,
regexp_substr(d.loc_trait_desc, '[^_]+', 1, 2),
d.store
UNION ALL
SELECT d.loc_trait,
d.brand,
d.store
FROM this_brand_loc_trait d
)
SELECT
'BRAND/ATTRIBUTE_1/ATTRIBUTE_2=S combination does not match any existing MIG_LOC_TRAITS/MIG_LOC_TRAITS_MATRIX setup', -- error_desc
FROM mig_als_int_cross_ref_dmf_ccid crs,
v_brand_store s
WHERE crs.attribute_2 = 'S'
AND crs.attribute_1 = s.store
AND s.is_store_min_brand = 'Y'
AND NOT EXISTS (SELECT 1
FROM valid_brand_loc_trait lt
WHERE lt.store = TO_NUMBER(crs.attribute_1)
AND lt.brand = crs.brand);
When I run the underlying SQL statement, it doesn't bring any record.
But If I run with the inserts, it inserts records on it.
The following statement is executed initially on the server:
ALTER SESSION FORCE PARALLEL DML PARALLEL 50;
If this statement is executed and then the insert is run, it inserted records.
But if this parallel statement is not executed, the insert query doesn't insert anything.
What can be the issue with the above parallel force and the query?
UPDATE: - Use Case
When running the Select statement under the Insert, it brings 0-Records
Just by un-commenting the insert, it inserts records from the same SQL
I have one sql that need convert string column to array and i have to filter with this column,sql like this:
select
parent_line,
string_to_array(parent_line, '-')
from
bx_crm.department
where
status = 0 and
'851' = ANY(string_to_array(parent_line, '-')) and
array_length(string_to_array(parent_line, '-'), 1) = 5;
parent_line is a varchar(50) column,the data in this like 0-1-851-88
question:
string_to_array(parent_line, '-') appear many times in my sql.
how many times string_to_array(parent_line) calculate in each row. one time or three times
how convert string_to_array(parent_line) to a parameter. at last,my sql may like this:
depts = string_to_array(parent_line, '-')
select
parent_line,
depts
from
bx_crm.department
where
status = 0 and
'851' = ANY(depts) and
array_length(depts, 1) = 5;
Postgres supports lateral joins which can simplify this logic:
select parent_line, v.parents, status, ... other columns ...
from bx_crm.department d cross join lateral
(values (string_to_array(parent_line, '-')) v(parents)
where d.status = 0 and
cardinality(v.parents) = 5
'851' = any(v.parents)
Use a derived table:
select *
from (
select parent_line,
string_to_array(parent_line, '-') as parents,
status,
... other columns ...
from bx_crm.department
) x
where status = 0
and cardinality(parents) = 5
and '851' = any(parents)
I am writting one query where one field is DIAL_NUMBER.
some values are 11 digit and some are 10 digits in that field. where it is 11 digit i need 2nd to 7th charcter and where it is 10 digit i need 1st to 6th character.
Then i need count of each individual series. i tried with this below approach, which is giving error.
Please help me in identifying the solution.
select dialled number, case
when length(Dialled_Number) = '11' then Substr(Dialled_Number, 2, 7)
else Substr(Dialled_Number, 1, 6)
end
count(*)
from Error_Event
Without knowing your expected results, I imagine you need to use group by with your query.
Perhaps something like this:
select case
when length(Dialled_Number) = 11 then Substr(Dialled_Number, 2, 7)
else Substr(Dialled_Number, 1, 6)
end,
count(*)
from Error_Event
group by case
when length(Dialled_Number) = 11 then Substr(Dialled_Number, 2, 7)
else Substr(Dialled_Number, 1, 6)
end
SQL Fiddle Demo
If it is MS SQL, you can use ROW_NUMBER() and COUNT function to get desired output.
DECLARE #TABLE TABLE(DIAL_NUMBER VARCHAR(20))
INSERT INTO #TABLE
SELECT '81243193812' UNION
SELECT '1829321874' UNION
SELECT '182932'
SELECT NPANXX, [Count] FROM
(
SELECT NPANXX,
COUNT(NPANXX) OVER (PARTITION BY NPANXX) AS [Count], DIAL_NUMBER,
ROW_NUMBER() OVER (PARTITION BY NPANXX ORDER BY DIAL_NUMBER) RN
FROM
(
SELECT DIAL_NUMBER,
CASE
WHEN LEN(DIAL_NUMBER) = 11 THEN SUBSTRING(DIAL_NUMBER,2, 7)
ELSE SUBSTRING(DIAL_NUMBER,1, 6)
END AS NPANXX
FROM #table
) Tmp
)FTMp
WHERE RN = 1
Sql Fiddle
The numbers are originally alpha numeric so I have a query to parse out the numbers:
My query here gives me a list of numbers:
select distinct cast(SUBSTRING(docket,7,999) as INT) from
[DHI_IL_Stage].[dbo].[Violation] where InsertDataSourceID='40' and
ViolationCounty='Carroll' and SUBSTRING(docket,5,2)='TR' and
LEFT(docket,4)='2011' order by 1
Returns the list of numbers parsed out.
For example, the number will be 2012TR557. After using the query it will be 557.
I need to write a query that will give back the missing numbers in a sequence.
Here is one approach
The following should return one row for each sequence of missing numbers. So, if you series is 3, 5, 6, 9, then it should return:
4 4
7 8
The query is:
with nums as (
select distinct cast(SUBSTRING(docket, 7, 999) as INT) as n,
row_number() over (order by cast(SUBSTRING(docket, 7, 999) as INT)) as seqnum
from [DHI_IL_Stage].[dbo].[Violation]
where InsertDataSourceID = '40' and
ViolationCounty = 'Carroll' and
SUBSTRING(docket,5,2) = 'TR' and
LEFT(docket, 4) = '2011'
)
select (nums_prev.n + 1) as first_missing, nums.n - 1 as last_missing
from nums left outer join
nums nums_prev
on nums.seqnum = nums_prev.seqnum + 1
where nums.n <> nums_prev.n + 1 ;
I've been struggling to create an Oracle SQL query that will tell me if my SDO table contains curves or arcs. I know that the sdo_elem_info contains the information I need, but I don't know how to use SQL to separate out the etype and interpretation from the sdo_elem_info.
So far, all I have is: select tbl.shape.sdo_elem_info from my_table tbl
You can use the TABLE function to extract the sdo_elem_info_array elements, then pivot that and aggregate the resulting rows to yield a row per element, with a column for offset, etype and interpretation.
Something like this should give you your query... (warning: untested)
WITH elem_info AS (
SELECT
TRUNC((ROWNUM - 1) / 3, 0) element_no
, MAX(DECODE(MOD(ROWNUM, 3), 1, t.COLUMN_VALUE, NULL)) offset
, MAX(DECODE(MOD(ROWNUM, 3), 2, t.COLUMN_VALUE, NULL)) etype
, MAX(DECODE(MOD(ROWNUM, 3), 0, t.COLUMN_VALUE, NULL)) interpretation
FROM my_table tbl
, TABLE(tbl.shape.sdo_elem_info) t
GROUP BY TRUNC((ROWNUM - 1) / 3, 0)
)
SELECT DECODE(COUNT(*), 0, 'false', 'true')
FROM elem_info ei
WHERE ei.etype IN (1005, 2005)
OR ei.interpretation IN (2, 4)