I have created the following tables.
CREATE TABLE table1 (
idx SERIAL PRIMARY KEY,
refs_person TEXT[],
id_gps TEXT
);
CREATE TABLE table2 (
idx SERIAL PRIMARY KEY,
id_person TEXT,
city TEXT,
location INTEGER
);
I populated them with this information.
Table 1
idx || refs_person || id_gps
1 || {id_per_234, id_per_456} || gps_20
2 || {id_per_568} || gps_23
3 || {id_per_345, id_per_334, id_per_340} || gps_45
Table 2
idx || id_person || city || location
1 || id_per_234 || Paris || 20
2 || id_per_999 || York || 20
3 || id_per_213 || Paris || 20
4 || id_per_334 || Paris || 32
If I try to find out id_person in Paris with location 20.
select id_person from table2 where city = 'Paris' and location = '20';
id_per_234
id_per_213
Then, if I try to find out refs_person with id_gps 20 for table 1
select refs_person from table1 where id_gps = '20';
{id_per_234, id_per_456}
I'm having an issue relating to finding the common element between this two results.
For the this example, I want to get id_per_234.
I have tried using intersect statement without any success.
Any ideas?
You need to unnest the array, best using a LATERAL join, before you can INTERSECT the results:
SELECT rp.rp
FROM table1
CROSS JOIN LATERAL unnest(table1.refs_person) AS rp(rp)
WHERE id_gps = 'gps_20'
INTERSECT
SELECT id_person
FROM table2
WHERE city = 'Paris' AND location = 20;
rp
------------
id_per_234
(1 row)
Related
I'd like some help with a query that I'm trying to build.
I have the following query that I'm building:
select sd.address,
sd.colour_code,
s.id as deactivated_id,
s.type,
'http://site/groups/' || c.group_id || '/user/' || c.subject_id as URL
from sensors s
join contracts c on s.contract_id=c.id
join sensordevices sd on sd.id=s.device_id
where s.begin_time is not null and
s.end_time is not null and
c.end_date is null and
not exists (select * from sensors sb
where sb.begin_time is not null and --b properly entered
sb.end_time is null and -- b active
sb.contract_id=s.contract_id and
s.type=sb.type and
s.end_time<=sb.begin_time)
;
Which generates a table like this (without the barcode column which I would like to add):
On which I would like a barcode column, but the barcode is not in the database but a derived attribute.
In order to get barcodes I was given the following query:
SELECT
ean || '' ||
(
10
-
(
(
SELECT
SUM(digit)
FROM (
SELECT
ROW_NUMBER() over () AS pos,
digit
FROM (
SELECT
REGEXP_SPLIT_TO_TABLE(
ean::TEXT,
''::TEXT
)::INT AS digit
) AS split
) AS sub
WHERE pos < LENGTH(ean::TEXT)
AND pos % 2 = LENGTH(ean::TEXT) % 2
)
+
(
SELECT
SUM(digit * 3)
FROM (
SELECT
ROW_NUMBER() over () AS pos,
digit
FROM (
SELECT
REGEXP_SPLIT_TO_TABLE(
ean::TEXT,
''::TEXT
)::INT AS digit
) AS split
) AS sub
WHERE pos < LENGTH(ean::TEXT)
AND pos % 2 = (LENGTH(ean::TEXT) - 1) % 2
)
) % 10
) % 10 as barcode
FROM
(select '0' || sd.type || '00000' || sd.address as ean
from sensors s
join sensordevices sd on s.device_id = sd.id
) as ean;
Which returns a table with a single column, barcode.
So, my question is, how can I use the second query to select the barcode for the first statement?
What I tried was the following:
On my query after select I added brc.barcode and after from (SECOND-LARGE-QUERY-HERE) brc, but I got this error: [53100] ERROR: could not write to file "base/pgsql_tmp/pgsql_tmp62390.6721": No space left on device which I assume is because it's trying to temporarily save a list of every possible barcode before executing the query. I also tried adding some constraints inside the nested query, but I got another error there.
Could someone help me with the query?
Thank you very much for your time,
Bill
I have the below postgres query that finds duplicate records in a database but I'm hoping to add in another condition so that I can say AT LEAST ONE of the duplicated records has the values of v.varfield_type_code = 's' AND v.field_content ~ 'Greendale student cards%' (from a table called sierra_view.varfield v ON p.record_id = v.record_id).
I tried an INNER JOIN and am looking into EXISTS. Does anyone have any insight? Thank you.
SELECT
p.birth_date_gmt, 'p' || rm2.record_num || 'a' AS "patron",
n.last_name || ' ' || n.first_name || ' ' || n.middle_name as name,
count(*) as cnt
FROM
sierra_view.patron_record p
JOIN sierra_view.patron_record_fullname n ON p.record_id =
n.patron_record_id
JOIN sierra_view.record_metadata rm2 on p.record_id = rm2.id
/* JOIN sierra_view.varfield v on p.record_id =v.record_id */
WHERE p.birth_date_gmt BETWEEN '01-01-2001' AND '12-31-2017'
GROUP BY 1,2, 3
HAVING COUNT(1) > 1
ORDER BY 2,1
You can put these conditions in the HAVING section:
JOIN sierra_view.varfield v on p.record_id = v.record_id
WHERE ...
GROUP BY ...
HAVING COUNT(*) > 1 AND COUNT(CASE WHEN v.varfield_type_code = 's' AND v.field_content ~ 'Greendale student cards%' THEN 1 END) > 0
So:
COUNT(*) > 1 = Only include duplicate records (you already do this)
COUNT(CASE WHEN v.varfield_type_code = 's' AND v.field_content ~ 'Greendale student cards%' THEN 1 END) > 0 = Count the grouped records based on those two conditions; if a record matches, it gets a 1, otherwise a NULL (implicit), and NULLs are not counted. So if at least one of the grouped records matches the criteria, the whole "group" will be included in the results; if not, they won't be included.
Also worth double checking whether ~ 'Greendale student cards%' is correct; ~ is for a regex check, while % is a wildcard symbol for LIKE, unless of course you do mean to search for a literal % character.
I have one table having data
Category. New data
Cost of equipment. 23
Price of equipments. 45
Cost of M&C. 13
Price of M&C. 12
And one another table having
Category
Equipments
M&C
Now i want data as below
Category Cost Price
Equipment 23 45
M&C 13 12
Can you please help me in solving this
You may try this. A better approach is to change your table design.
Note that while joining I had to use RTRIM to remove s from equipments. I am not aware of any other variations in your data which might not match between the two tables. Please change the join conditions appropriately ( or use a REGEXP match instead of ILIKE if they don't )
SQL Fiddle
PostgreSQL 9.6 Schema Setup:
CREATE TABLE Table1
(Category varchar(19), New_data int)
;
INSERT INTO Table1
(Category, New_data)
VALUES
('Cost of equipment', 23),
('Price of equipments', 45),
('Cost of M&C', 13),
('Price of M&C', 12)
;
CREATE TABLE Table2
(Category varchar(10))
;
INSERT INTO Table2
(Category)
VALUES
('Equipments'),
('M&C')
;
Query 1:
WITH t1
AS (
SELECT b.category
,a.new_data
FROM TABLE1 a
INNER JOIN TABLE2 b ON a.Category ILIKE '%cost%' || RTRIM(b.Category, 's') || '%'
)
,t2
AS (
SELECT c.category
,a.new_data
FROM TABLE1 a
INNER JOIN TABLE2 c ON a.Category ILIKE '%price%' || RTRIM(c.Category, 's') || '%'
)
SELECT t1.category
,t1.new_data AS cost
,t2.new_data AS price
FROM t1
INNER JOIN t2 ON t1.category = t2.category
Results:
| category | cost | price |
|------------|------|-------|
| Equipments | 23 | 45 |
| M&C | 13 | 12 |
I don't have PostGIS, hence I use built-in functions.
I have got below query working correctly.
However, I need to find these values from the table
select area(circle( (polygon '(43.5042,-96.8391),(33.508,-112.1254),(33.4912,-111.9237),(33.4912,-111.9237),(33.4912,-111.9237),(38,-97)' ) ))
Below queries return error.
Any help on how to have the polygon from fields from a table?
select id, polygon '('||array_to_string(array_agg('('||latdec_src||','||longdec_src||')'),',') ||')' from access where id='99999' and time >= '2017-01-03' and time < '2017-01-04' group by 1
select id, polygon array_agg('('||latdec_src||','||longdec_src||')') from access where id='99999' and time >= '2017-01-03' and time < '2017-01-04' group by 1
select id, polygon array_agg(point(latdec_src,longdec_src)) from acesss where id='99999' and time >= '2017-01-03' and time < '2017-01-04' group by 1
You can do something similar to:
WITH points (lat, lng, sort_order) AS
(
VALUES
(43.5042, -96.8391, 1),
(33.508, -112.1254, 2),
(33.4912,-111.9237, 3),
(33.4912,-111.9237, 4),
(33.4912,-111.9237, 5),
(38, -97, 6)
)
SELECT
area(circle(polygon( string_agg(one_point, ',') ))) AS area
FROM (
SELECT
'(' || lat || ',' || lng || ')' AS one_point
FROM
points
ORDER BY
sort_order
) AS s0 ;
If I understand well your tables (whose definitions you can include in your question), that would be
SELECT
area(circle(polygon( string_agg(one_point, ',') ))) AS area
FROM (
SELECT
'(' || latdec_src || ',' || longdec_src || ')' AS one_point
FROM
access
WHERE
id ='99999' and time >= '2017-01-03' and time < '2017-01-04'
ORDER BY
time
) AS s0 ;
(I really don't know if this is going to give you an area if you just use longitude and latitude values; but that's another story.)
SELECT coalesce(RPAD('IN',16,' ') || RPAD( M.CASETYPE||'/' || M.CASENUMBER || '/' || M.CASEYEAR,16, ' '),' ') as inmatter
FROM (
select level as LEV, l1.LINKCASECCIN as CCI ,l1.linkcategorycode as lcode
from hclive.LINKEDMATTERS l1
start with l1.MAINCASECCIN ='001003201400100' and l1.linkcategorycode='I'
connect by nocycle prior l1.LINKCASECCIN = l1.MAINCASECCIN and l1.linkcategorycode = 'I'
) s1,
hclive.MAIN M
where M.CCIN=CCI
connect by is done with a recursive common table expression in Postgres.
with recursive tree as (
select 1 as level, l1.linkcaseccin as cci, l1.linkcategorycode as lcode
from hclive.linkedmatters l1
where l1.maincaseccin ='001003201400100'
and l1.linkcategorycode='I'
union all
select p.level + 1, c1.linkcaseccin as cci, c1.linkcategorycode as lcode
from hclive.linkedmatters c1
join tree p on p.maincaseccin = c1.linkcaseccin
where c1.linkcategorycode='I'
)
select coalesce(rpad('IN',16,' ') || rpad( m.casetype||'/' || m.casenumber || '/' || m.caseyear,16, ' '),' ') as inmatter
from tree t
join hclive.main M on m.ccin = t.cci;
The level column does not seem to be necessary as you don't use it at all in your query, but I left in there as an example to get the same information in Postgres.