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)
Related
im trying to make the query more efficient, is there a way to use an alias in order to call regexp_substr only once?
this is the sql query:
SELECT *,
(SUBSTRING(REGEXP_SUBSTR(A, '(://([a-zA-Z0-9]+):)', 1, 1, 'c'), 4, LENGTH(REGEXP_SUBSTR(A, '(://([a-zA-Z0-9]+):)', 1, 1, 'c')) - 4)) as custom
FROM table
No need for a second regexp_substr, simply use 2 argument SUBSTRING. (I.e. substring from position 4 to the end):
SELECT *,
SUBSTRING(REGEXP_SUBSTR(A, '(://([a-zA-Z0-9]+):)', 1, 1, 'c'), 4) as custom
FROM table
https://docs.snowflake.com/en/sql-reference/functions/substr.html
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;
I am looking at different breeds of cattle and their AnimalTypeCode , BreedCateoryID and resultant Growth.
I have the following query
SELECT DATEPART(yyyy,[KillDate])
,[AnimalTypeCode]
,AVG([Growth])
,[BreedCategoryID]
FROM [dbo].[tblAnimal]
WHERE (AnimalTypeCode='C'
or AnimalTypeCode= 'E')
GROUP BY DATEPART(yyyy,[KillDate])
,[AnimalTypeCode]
,[BreedCategoryID]
GO
This query is good and gives me almost what I want, but BreedCategoryID is numbered 1 through 7 and I would like to group them:
(1 = Pure Dairy),
(2 and 3 = Dairy)
(4, 5, 6 and 7 = Beef)
So instead of getting the mean Growthrate for each BreedCategoryID I would like to get the average for Pure Dairy, Dairy, and Beef.
Any help greatly appreciated!
You can assign a new "variable" using cross apply in the from clause:
SELECT YEAR(KillDate]), a.AnimalTypeCode, v.grp,
AVG([Growth])
FROM [dbo].[tblAnimal] a CROSS APPLY
(VALUES (CASE WHEN a.BreedCategoryID IN (1) THEN 'Pure Dairy'
WHEN a.BreedCategoryID IN (2, 3) THEN 'Dairy'
WHEN a.BreedCategoryID IN (4, 5, 6, 7) THEN 'Beef'
END)
) as v(grp)
WHERE a.AnimalTypeCode IN ('C', 'E')
GROUP BY YEAR(KillDate]), a.AnimalTypeCode, v.grp;
Note that I also introduced table aliases and qualified all the column references.
Do the calculations in a derived table (the subquery). GROUP BY its result:
select killyear, [AnimalTypeCode], AVG([Growth]), BreedCat
(
SELECT DATEPART(yyyy,[KillDate]) killyear
,[AnimalTypeCode]
,[Growth]
,case when [BreedCategoryID] = 1 then 'Pure Dairy'
when [BreedCategoryID] in (2, 3) then 'Dairy'
when [BreedCategoryID] in (4, 5, 6, 7) then 'Beef'
end BreedCat
FROM [dbo].[tblAnimal]
WHERE (AnimalTypeCode='C'
or AnimalTypeCode= 'E')
) dt
GROUP BY killyear
,[AnimalTypeCode]
,BreedCat
This is a beginner-question relating arrays. I hope the answer is simple.
The example is taken from Oracle Spatial, but I think it is valid for all arrays.
I have this SELECT:
SELECT
D.FID
, D.GEOM.SDO_ELEM_INFO -- column GEOM contains spatial data
FROM
my_table D
I get this result:
73035 MDSYS.SDO_ELEM_INFO_ARRAY(1, 2, 1)
73036 MDSYS.SDO_ELEM_INFO_ARRAY(1, 4, 3, 1, 2, 1, 11, 2, 2, 19, 2, 1)
73037 MDSYS.SDO_ELEM_INFO_ARRAY(1, 2, 1)
Now I want to SELECT all rows where (1,2,1) is defined:
SELECT
D.FID
, D.GEOM.SDO_ELEM_INFO
FROM
my_table D
WHERE
-- Pseudo-Code is following
D.GEOM.SDO_ELEM_INFO is "(1, 2, 1)";
So, in simple words: "array_from_row = defined_array".
I found a lot about IMPLODE and TABLE and COLLECT etc. But how to define a clause on two arrays?
Thanks for help!
Try IN clause, you can also use both
SELECT
D.FID
, D.GEOM.SDO_ELEM_INFO
FROM
my_table D
WHERE
D.GEOM.SDO_ELEM_INFO in (1, 2, 1) or ( D.GEOM.SDO_ELEM_INFO = 1 or D.GEOM.SDO_ELEM_INFO = 2 or D.GEOM.SDO_ELEM_INFO = 3);
So in this case I want to display every ID where the corresponding value is 1. However, in the case below where the ID is 4, I don't want it to display the 4's where the value is 1, I just want it to not show 4 at all. If I do a WHERE value LIKE '1', it'll show me the two IDs of 4 where the value is 1. Is there a way to not show 4 at all? Thanks in advance.
ID:.......1...2...3...4...4...4...5
Value:....1...1...1...1...2...1...1
(This is on Microsoft SQL Server management studio by the way)
If you just want the ids, then use aggregation:
select id
from t
group by id
having min(value) = 1 and max(value) = 1;
To add on Gordon's answer
I would add a count since it seems your data has multiple 1s in that case if you have two 1s you'd have it as both min and max
select id
from t
group by id
having min(value) = 1 and max(value) = 1 and count(value) = 1;
You could also use
select id from t group by id having sum(value) = 1 and count(value) = 1;
with cte as (
select * from (values
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(4, 2),
(4, 1),
(5, 1)
) as x(ID, Value)
)
select *
from cte
where ID not in (
select ID
from cte
where Value > 1
);