Select table value by range - sql

In my table I have the primary key id. It is a two byte varchar type.
If the id is from 00 to 89 then it returns a set of data, otherwise returns different data. My query in the stored procedure is
BEGIN
select * from MyTable where (id like '0%' or
id like '1%' or
id like '2%' or
id like '3%' or
id like '4%' or
id like '5%' or
id like '6%' or
id like '7%' or
id like '8%')
and status = 'active'
union all
select * from MyTable where id like '9%' and status='inactive'
END
My question is how can I improve it? May I convert the string to number then using >89 or <90?

You can also use regular expressions:
select * from MyTable
where REGEXP_LIKE(id, '^[0-8][0-9]') and status='active'
or REGEXP_LIKE(id, '^9[0-9]') and status='inactive'

How about:
select * from mytable
where ( id < '9' and status = 'active' )
or ( id >= '9' and status = 'inactive' )

Related

Update table using with temp CTE

%sql
with temp1 as
(
select req_id from table1 order by timestamp desc limit 8000000
)
update table1 set label = '1' where req_id in temp1 and req_query like '%\<\/script\>%'
update table1 set label = '1' where req_id in temp1 and req_query like '%aaaaa%'
update table1 set label = '1' where req_id in temp1 and req_query like '%bbbb%'
getting error:
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException: org.apache.spark.sql.catalyst.parser.ParseException:
mismatched input 'in' expecting {, ';'}(line 6, pos 93)
can someone advise? what will be less costly to ask the database the same question?
select req_id from table1 order by timestamp desc limit 8000000
This is not allowed: where req_id in temp1. temp1 is not a list, but the result of a query and should be used like another table.
You might rather write something like this:
update table1
set label = '1'
where req_id in (select req_id from table1 order by timestamp desc limit 8000000)
and req_query like '%\<\/script\>%'
You can use update with join instead of IN clause.
Delta does not support updating tables using inner join but you can use MERGE I think. Something like this:
WITH temp1 AS (
SELECT req_id FROM table1 ORDER BY timestamp DESC LIMIT 8000000
)
MERGE INTO table1 a
USING temp1 b
ON (a.req_id = b.req_id)
WHEN MATCHED THEN
UPDATE SET a.label = CASE WHEN a.req_query LIKE '%\<\/script\>%' THEN '1'
WHEN a.req_query LIKE '%aaaaa%' THEN '2'
WHEN a.req_query LIKE '%bbbb%' THEN '3'
ELSE a.label
END

NULL id in SQL statement

Select *
from tbl
where id = '1fa3bcdc9a1cf60f02a2ae774e2cf166'
or matching_id = 'ea74c270-65fd-46d0-898b-faf1a7bf7e16'
My id column below comes back with a NULL for one of my events. They are related using the matching_id key. Is there a way I can write a case statement to populate that id field so its not NULL?
You can use coalesce() and in case of null id fetch a value (any value?) for the id matching the matching_id like this:
Select
coalesce(
id,
(select max(id) from tbl where matching_id = 'ea74c270-65fd-46d0-898b-faf1a7bf7e16')
) as id,
matching_id,
event_name
from tbl
where
id = '1fa3bcdc9a1cf60f02a2ae774e2cf166'
or
matching_id = 'ea74c270-65fd-46d0-898b-faf1a7bf7e16'
Edit.
Try this in case of unknown values:
Select
coalesce(
t.id,
(select max(id) from tbl where matching_id = t.matching_id)
) as id,
coalesce(
t.matching_id,
(select max(matching_id) from tbl where id = t.id)
) as matching_id,
t.event_name
from tbl t
Ended up writing something like this..
[snapshot 1
with find_event AS (
Select tbl1. id, tbl1.matching_id
from tbl1
where tbl1.id IS NOT NULL
)
Select
CASE WHEN find_event. id IS NOT NULL
THEN find_event. id
WHEN find_event.id IS NULL
THEN tbl2. id
ELSE tbl2. id
END as final_id,
tbl2.matching_id,
tbl2. id,
tbl2.event_name,
find _event. id as find_canonical_id
from tbl2
left JOIN find_event on find_event.matching_id = tbl2.matching_id
where
tbl2.transaction_canonical_id = '1fa3bcdc9a1cf60f02a2ae774e2cf166'
or
tbl2.matching_id = 'ea74c270-65fd-46d0-898b-faf1a7bf7e16'
If you want to replace the column values with the values from your parameters, you could use something like this:
with ids (id, mid) as (
values
('1fa3bcdc9a1cf60f02a2ae774e2cf166', 'ea74c270-65fd-46d0-898b-faf1a7bf7e16')
)
Select coalesce(tbl.id, ids.id),
tbl.matching_id,
tbl.event_name
from tbl
join ids on ids.id = tbl.id or ids.mid = tbl.matching_id;
You may be able to utilize the ISNULL() function for this. Maybe something like:
Select
ISNULL(id, matching_id) AS [myid],
matching_id,
event_name
from tbl
where id = '1fa3bcdc9a1cf60f02a2ae774e2cf166'
or matching_id = 'ea74c270-65fd-46d0-898b-faf1a7bf7e16'

SQL select statement in where clause

Hi there I am trying to execute a query but cannot seem to get it right.
SELECT *
FROM table
WHERE id IN (SELECT *
FROM table
WHERE description = 'A')
AND description = 'B'
Above is the query that I have got, the select * from table where description = A works as expected when ran alone I just need to make the where clause to work so I can see any id that has a description of A and B.
You will be getting multiple columns from the sub query when I assume you only want the id column:
SELECT *
FROM table
WHERE id IN (SELECT id
FROM table
WHERE description = 'A')
AND description = 'B'
No need for the select in the where clause
SELECT *
FROM table
WHERE id IN ('A', 'B')
Try this:
SELECT *
FROM table
WHERE description IN ('A', 'B')
it should be:
select * from table where id in (select id from table where description = 'A') and description = 'B'
but this query will give you zero result as you select records with description = 'A' and description = 'B', if you want to get records with either description of A or B, then you should write as
select * from table where description = 'A' or description = 'B'
or
select * from table where description in ('A','B')
SELECT distinct AnaTablo.Id , AnaTablo.FirmaAdi , AnaTablo.FirmaId , AnaTablo.KayitTarihi ,
users.Email Personel, (SELECT top 1 sabitler.Ayar from tblSabitAyarlar sabitler WHERE sabitler.Tur = 29 and sabitler.Deger in
(SELECT top 1 IslemId from tblEFaturaTakipIslem Islem WHERE AnaTablo.Id = Islem.EFaturaTakipId order by KayitTarihi desc))YapilanIslem,
AnaTablo.Eposta , AnaTablo.Aciklama
from tblEFaturaTakip AnaTablo left join AspNetUsers users on AnaTablo.PersonelId = users.Id

How do you make an Oracle SQL query to

This table is rather backwards from a normal schema, and I'm not sure how to get the data I need from it.
Here is some sample data,
Value (column) Info (column)
---------------------------------------------
Supplier_1 'Some supplier'
Supplier_1_email 'foo#gmail.com'
Supplier_1_rating '5'
Supplier_1_status 'Active'
Supplier_2 'Some other supplier'
Supplier_2_email 'bar#gmail.com'
Supplier_2_rating '4'
Supplier_2_status 'Active'
Supplier_3 'Yet another supplier'
...
I need a query to find the email of the supplier which has the highest rating and is currently of status 'Active'.
select
m.sup_email, r.sup_rating
from
(select substr(value, 1, length(value) - length('_email') as sup_name, info as sup_email from table where value like '%_email') as m
left join
(select substr(value, 1, length(value) - length('_rating') as sup_name), info as sub_rating from table where value like '%_rating') as r on m.sup_name = r.sup_name
order by
sup_rating desc
limit
1;
For a single pass solution, try:
select "email" from
(select
substr("value", 1, 8 + instr(substr("value", 10, length("value")-9),'_')) "supplier",
max(case when "value" like '%_status' then "info" end) as "status",
max(case when "value" like '%_rating' then cast("info" as integer) end) as "rating",
max(case when "value" like '%_email' then "info" end) as "email"
from "table" t
where "value" like '%_rating' or "value" like '%_email' or "value" like '%_status'
group by substr("value", 1, 8 + instr(substr("value", 10, length("value")-9),'_'))
having max(case when "value" like '%_status' then "info" end) = 'Active'
order by 3 desc
) where rownum = 1
(Column names are all double-quoted as some are reserved words.)
Expanding on Mike's excellent suggestion:
CREATE VIEW supplier_names AS
SELECT SUBSTR(Value,INSTR(Value,'_')+1) AS supplier_id
,Info AS supplier_name
FROM the_table
WHERE INSTR(Value,'_',1,2) = 0;
CREATE VIEW supplier_emails AS
SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1)
AS supplier_id
,Info AS supplier_email
FROM the_table
WHERE Value LIKE '%email';
CREATE VIEW supplier_ratings AS
SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1)
AS supplier_id
,Info AS supplier_rating
FROM the_table
WHERE Value LIKE '%rating';
CREATE VIEW supplier_statuses AS
SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1)
AS supplier_id
,Info AS supplier_rating
FROM the_table
WHERE Value LIKE '%status';
The queries will perform like dogs, so I'd suggest you look into creating some virtual columns, or at least function-based indexes, to optimise these queries.

How to get result from a column with combined data?

data:
id bb
1 14,35
2 5,11,12,125,36
3 3,23,45,15,1
4 651
5 5,1,6
6 1,7
For example, i wan't get id which with value '1'. So id(3,5,6) should return , but not others with '14' or '11'.
DB: Mysql
This is not the most efficient solution but it might give you what you want off the table:
select id from MyTable where bb like '%,1,%' union
select id from MyTable where bb like '1,%' union
select id from MyTable where bb like '%,1' union
select id from MyTable where bb like '1'
cheers
select * from test where find_in_set('1',bbb)
or
select * from test where bbb REGEXP '(^|,)1(,|$)'
Am I missing something?
SELECT *
FROM MyTable
WHERE (id = 3) or (id = 5) or (id = 6)
you can do like this
select * from mytable where id like '14%' or '11%'