I got a postgres function that gives me this (sample) 2D array
{{0.82,60.64,1006},{2.0,59.64,1006},{9.9,60.304,999}}
I want to get the first item of each row, like this:
{0.82,2.0,9.9,}
Any way of doing this directly on Postgres/SQL? Thanks
PostrgeSql provides array ops you want. Demo
CREATE TABLE sample (
id int,
va decimal[3][3]
);
INSERT INTO sample
VALUES (1, '{{0.82,60.64,1006},{2.0,59.64,1006},{9.9,60.304,999}}');
select id, array_agg(v) res
from (
select id, unnest(va[:][1:1]) v
from sample
) t
group by id
Returns
id res
1 {0.82,2.0,9.9}
Related
I have a simple db table:
create table if not exists players
(
id bigint,
name text,
results text[]
);
Now I would like to create select query, where I want only rows with passed results. So I created a scala code with doobie:
def getPlayers(id: Int, result: String): Query[Int] = {
sql"select id from players where results ? $result".query[Int]
}
But it didn't work as expected. My question is how to select from array column in postgresql? Currently I have results as an array, but I could change it to jsonb if it is easier.
You can use the following query:
select id from players where $result = any(results);
You can find more information here:
https://www.postgresql.org/docs/current/functions-comparisons.html
I have a column that contains complex string and I am trying to extract out values from this string column. Here is the temp table and values -
with temp as (
select 1 as event_id, ';t-Tew00;1;1.00;252=100.00,;SM-R190;1;1.00;252=200.00,;SM-G998B/DS;1;6347.00;252=300.00,;EF-PG99P;1;249.00;252=400.00' as event_list union all
select 2 as event_id, ';asdI-Tww5300;1;1.00;252=99.00,,;EP-TA845;.252=49.00' as event_list union all
select 3 as event_id, ';asdI-Tww5300;1;1.00;252=10.00,,;EP-TA845;,.252=20.00,:etw:1002:2020,'
)
select *
from temp
I want to extract out all the double/int values after the appearance of 252= in the event_list column. For instance, in the first record, I would like to extract the values 100.00,200.00,300.00 and 400.00
I would like to add a separate column in the output that will add all such values together. So the output column for first record would be 1000.00. Likewise, 99+49 for 2nd record and 10+20 for 3rd record.
If no such appearance of 252= appears then output must be 0.
How can I achieve this in BigQuery
Try below
select event_id,
(
select ifnull(sum(cast(value as float64)), 0)
from unnest(regexp_extract_all(event_list, r'252=(\d*.?\d*)')) value
) as total_252
from temp
if aplied to sample data in your question - output is
I am trying to develop a university database with the help of nested tables, I have successfully created all other nested tables required and inserted data as well, but while inserting data into marks table I am facing problem of inconsistent datatype.
codes:
CREATE OR REPLACE TYPE MODULE_MARKS;
CREATE OR REPLACE TYPE MM_NT_TYPE AS TABLE OF REF MODULE_MARKS;
CREATE OR REPLACE TYPE MODULE_MARKS AS OBJECT
(
MODULE REF MODULE_T, MARKS_OBTAINED, TOTAL_MARKS, STATUS
)
CREATE TABLE MARK_TAB
(
student ref student_t,
modules_marks mm_nt_type
)
I am able to insert reference to student correctly but I want to insert data into module_marks.
Tried doing :
INSERT INTO MARK_TAB VALUES((SELECT REF(S) FROM STUDENT_TAB S WHERE
S.S_ID=1),
MM_NT_TYPE( MODULE_MARKS_T((SELECT REF (M) FROM MODULE_TAB M WHERE
M.MODULE_ID =1),
90,100,'PASS')));
this shoes the error ORA-00932. EXPECTED REFERENCE OF MODULE_MARKS_T GOT MODULE_MARKS_T.
It seems a familiar structure to me. Maybe I have created the same structure for one of my projects.
I think you are confused when inserting the record in the column having a type which is table of REF.
I have COURSES_TABLE_TYPE which is table of REF COURSES_T and courses table is table of COURSES_T;
I suggest you do the following:
INSERT INTO DEPARTMENT VALUES (
1,
COURSES_TABLE_TYPE(( -- REFs of single records delimited by comma
SELECT
REF(C)
FROM
COURSE C
WHERE
COURSE_ID = 1
),(
SELECT
REF(C)
FROM
COURSE C
WHERE
COURSE_ID = 2
))
);
MM_NT_TYPE is a collection of REF MODULE_MARKS whereas you are passing MODULE_MARKS objects and not references. Instead, you need to have a table containing containing MODULE_MARKS objects that you can reference:
CREATE TABLE module_marks_tab OF module_marks;
Then you can reference those objects. For example:
INSERT INTO mark_tab VALUES (
( SELECT REF(s) FROM students s WHERE id = 2 ),
MM_NT_TYPE(
( SELECT REF( m ) FROM module_marks_tab m WHERE m.module.id = 1 AND marks_obtained = 3 ),
( SELECT REF( m ) FROM module_marks_tab m WHERE m.module.id = 3 AND marks_obtained = 8 )
)
);
db<>fiddle
I am storing some ids and names in a jsonb array of object like this
[{"id":"1","name":"abc"},{"id":"2","name":"cde"}]
My table looks like this
id userinfo
1 [{"id":"1","name":"abc"},{"id":"2","name":"cde"}]
2 [{"id":"3","name":"fgh"},{"id":"4","name":"ijk"}]
I am trying to select all the records with id 1 but I just want to get ids in userinfo object I don't want names
I tried this
select distinct userinfo->'name' from table where id = 1
but this is giving me null value
This will work with this query
select distinct userinfo->0->'name' from table where id = 1
but I don't know the index so how can I use this query to get my desired result
Thanks
You need to normalize the data by unnesting the array, then you can access each element.
select ui.info ->> 'id' as id,
ui.info ->> 'name' as name
from the_table t
cross join lateral jsonb_array_elements(t.userinfo) as ui(info)
where t.id = 1;
Online example: http://rextester.com/FCNM11312
Take the following table:
CREATE TABLE test(id serial primary key, txt text);
INSERT INTO test (id,txt) values (1,'one'),(2,'two'),(3,'three')
and custom type:
CREATE TYPE tttpe AS (id integer, name varchar(32), greee integer);
I am converting a query like this:
SELECT id, txt, (id+10) as gree FROM test ORDER BY 2
where the 2 is dynamic, to a query like this:
SELECT (id, txt, (id+10))::tttpe FROM test; --order by!?
but I want to order it by a member of the custom type, for example txt. How do I do this? Ideally I'd like to be able to use an integer index for the nth property but if that's not possible I can work around it.
UPDATE:
Based on Clodoaldo Neto
s answer I came up with the following:
SELECT (id,txt,g)::tttpe FROM (select id, txt, (id+10) FROM test ORDER BY 2) AS s;
although in practice I have 40+ fields, so having to list them twice is a pain.
select (tt).id, (tt).name, (tt).greee, tt
from (
select (id, txt, id+10)::tttpe as tt
from test
) s
order by 3 desc
Without the subselect
select
((id, txt, id+10)::tttpe).id,
((id, txt, id+10)::tttpe).name,
((id, txt, id+10)::tttpe).greee,
(id, txt, id+10)::tttpe as tt
from test
order by 3 desc
Edit due to very important context change in the commentaries
The ordering done inside a function or a subselect is not guaranteed to be the one of its output, so do not order inside them. But the good news is that it is much easier to access each member of the type from a function
create or replace function get_tt()
returns tttpe as $$
select (id, txt, id+10)::tttpe as tt
from test;
$$ language sql;
select id, name, greee
from get_tt()
order by 3 desc;
But if you want the original object as in the below query then you are back to square one
select get_tt();