sql alias to function for reuse in select - sql

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

Related

SQL ARRAY: Select ID from my_table where "arrayvalue" = "defined_arrayvalue"

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);

SQL Server substring throws error "multiple results"

I use Microsoft SQL Server 2016.
I have a column that is called Failover and looks like his:
$D$Failov:12345:54362:28564
$D$Failov:12345:
$D$Failov:86905:45634
I want that number so I use :
select substring(failover, 10, 5)
from dbo.f009
where failover like '$D$Failov:%'
It works fine, but if I want a second column called Account, it crashed with multiple results…
Select
account,
(Select substring(failover, 10, 5) AS "1.Result"
from dbo.f009
where Failover like '$D$Failov:%')
from
f009
where
Failover like '$D$Failov:%'
How to fix this ?
Is there a simple way to take the second number and third? I can do it with:
substring(failover, 16, 5), substring(failover, 22, 5)
etc etc but it don't want to repeat myself.
You can repeat the string operations:
select substring(failover, 11, 5) as num1,
substring(failover, 17, 5) as num2,
substring(failover, 23, 5) as num3
from dbo.f009
where failover like '$D$Failov:%';
You can also phrase this as a recursive CTE, if you have an indefinite number of values:
with t as (
select * from (values ('$D$Failov:12345:54362:28564'), ('$D$Failov:12345:')) v(failover)
),
cte as (
select failover, convert(varchar(max), NULL) as acct, convert(varchar(max), stuff(failover, 1, 10, '')) as rest, 0 as lev
from t
union all
select failover, left(rest, 5), stuff(rest, 1, 6, ''), lev + 1
from cte
where rest > ':'
)
select failover, acct, lev
from cte
where lev > 0;
Here is a db<>fiddle.
It seems that what you want can be achieved with a simple query:
Select account, substring(failover,10,5) AS "1.Result"
from dbo.f009
where Failover like '$D$Failov:%'

sql query to determine if oracle spatial table contains curves

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)

Performing a prefix computation using SQL without defined procedures

I have a table with a column of integers - I need a way to generate the "prefix" of this column in another table.
For e.g.
I have 1, 0, 0, 0, 1, 0, 1, 0, 0 as the input
I need 1, 1, 1, 1, 2, 2, 3, 3, 3 as the output
This needs to be done in SQLite's SQL dialect , no user defined functions or stored procedures are possible.
try something like this:
select value,
(select sum(t2.value) from table t2 where t2.id <= t1.id ) as accumulated
from table t1
from: SQLite: accumulator (sum) column in a SELECT statement
So to insert from input table to output table you need following query:
INSERT INTO output
SELECT id,
(SELECT sum(i1.value) FROM input AS i1 WHERE i1.rowid <= i2.rowid) as VALUE
FROM input AS i2

How to do equivalent of "limit distinct"?

How can I limit a result set to n distinct values of a given column(s), where the actual number of rows may be higher?
Input table:
client_id, employer_id, other_value
1, 2, abc
1, 3, defg
2, 3, dkfjh
3, 1, ldkfjkj
4, 4, dlkfjk
4, 5, 342
4, 6, dkj
5, 1, dlkfj
6, 1, 34kjf
7, 7, 34kjf
8, 6, lkjkj
8, 7, 23kj
desired output, where limit distinct=5 distinct values of client_id:
1, 2, abc
1, 3, defg
2, 3, dkfjh
3, 1, ldkfjkj
4, 4, dlkfjk
4, 5, 342
4, 6, dkj
5, 1, dlkfj
Platform this is intended for is MySQL.
You can use a subselect
select * from table where client_id in
(select distinct client_id from table order by client_id limit 5)
This is for SQL Server. I can't remember, MySQL may use a LIMIT keyword instead of TOP. That may make the query more efficient if you can get rid of the inner most subquery by using the LIMIT and DISTINCT in the same subquery. (It looks like Vinko used this method and that LIMIT is correct. I'll leave this here for the second possible answer though.)
SELECT
client_id,
employer_id,
other_value
FROM
MyTable
WHERE
client_id IN
(
SELECT TOP 5
client_id
FROM
(
SELECT DISTINCT
client_id
FROM
MyTable
) SQ
ORDER BY
client_id
)
Of course, add in your own WHERE clause and ORDER BY clause in the subquery.
Another possibility (compare performance and see which works out better) is:
SELECT
client_id,
employer_id,
other_value
FROM
MyTable T1
WHERE
T1.code IN
(
SELECT
T2.code
FROM
MyTable T2
WHERE
(SELECT COUNT(*) FROM MyTable T3 WHERE T3,code < T2.code) < 5
)
-- Using Common Table Expression in Microsoft SQL Server.
-- LIMIT function does not exist in MS SQL.
WITH CTE
AS
(SELECT DISTINCT([COLUMN_NAME])
FROM [TABLE_NAME])
SELECT TOP (5) [[COLUMN_NAME]]
FROM CTE;
This works for ‍‍MS SQL if anyone is on that platform:
SET ROWCOUNT 10;
SELECT DISTINCT
column1, column2, column3,...
FROM
Table1
WHERE ...