Little issue on a Postgres database, being managed in Acqua Data Studio:
I need a solution to create a SELECT that concatenates many views into one table. There are more than 10 views.
One central may have many IDs, and one ID may have many centrals. So, the main table's PK would be the central-ID thing.
One example that applies (assuming that exist only 3 tables), as follows:
VIEW1:
central | ID | MAP
--------------------------------
A | 01 | MAP1
A | 02 | MAP1
A | 03 | -
B | 01 | MAP3
B | 02 | -
C | 01 | -
VIEW2:
central | ID | CAMEL
--------------------------------
A | 01 | CAP1
B | 01 | CAP1
B | 02 | CAP2
B | 03 | CAP3
D | 01 | -
VIEW3:
central | ID | NRRG
--------------------------------
A | 01 | NRRG2
B | 01 | -
C | 01 | -
D | 05 | NRRG1
.
.
.
Resulting Table:
central | ID | MAP | CAMEL | NRRG
--------------------------------------------------
A | 01 | MAP1 | CAP1 | NRRG2
A | 02 | MAP1 | |
A | 03 | - | |
B | 01 | MAP3 | CAP1 | -
B | 02 | - | CAP2 |
B | 03 | | CAP3 |
C | 01 | - | | -
D | 01 | | - |
D | 05 | | | NRRG1
Any central-ID that appears in any of the 10+ tables need to enter in the concatenated table.
I surely don't care about blank spaces on those columns that don't have a correspondent into the other columns...
The important thing is to get, in each ID-central row every correspondent value that is present on the other tables. PS: "-" is a value!
I thought about a FULL OUTER JOIN, but whatching the references in manual I can't see a way to do it perfectly...
Thanks, fellas!
SQL Fiddle
select central, id, map, camel, nrrg
from
v1
full outer join
v2 using (central, id)
full outer join
v3 using (central, id)
order by central, id
;
central | id | map | camel | nrrg
---------+----+------+-------+-------
A | 1 | MAP1 | CAP1 | NRRG2
A | 2 | MAP1 | |
A | 3 | | |
B | 1 | MAP3 | CAP1 |
B | 2 | | CAP2 |
B | 3 | | CAP3 |
C | 1 | | |
D | 1 | | |
D | 5 | | | NRRG1
A full outer join is extra complicated when you have composite keys. Instead, use the union all/group by method:
select central, id, max(map) as map, max(camel) as camel, max(nrrg) as nrrg
from ((select central, id, map, null as camel, null as nrrg
from view1
) union all
(select central, id, null as map, camel, null as nrrg
from view2
) union all
(select central, id, null as map, null as camel, nrrg
from view3
)
) v
group by central, id;
Related
I have two tables with inner join. I have to conditionlly select only one row from right table based on the existence of a value in categorical column.
Condition: If blue exists, select blue else select green
Table-A:
| ID | Name |
| ---| ------|
| 01 | row |
| 02 | row |
| 03 | row |
Table-B:
| ID | CatCol |
| ---| --------|
| 01 | blue |
| 01 | green |
| 01 | red |
| 02 | green |
| 02 | red |
| 03 | blue |
Expected:
| ID | CatCol |
| ---| --------|
| 01 | blue |
| 02 | green |
| 03 | blue |
Consider below approach
select a.ID, string_agg(CatCol, '' order by if(CatCol = 'blue', 1, 2) limit 1) CatCol
from table_a a left join table_b b
on a.ID = b.ID and CatCol in ('blue', 'green')
group by ID
if applied to sample data in your question - output is
This should work for you:
SELECT b.ID, MIN(b.CatCol) as CatCol
FROM table_b b
INNER JOIN table_a a ON
b.id = a.id
GROUP BY b.ID
need your help. I guess/hope there is a function for that. I found "CONNECT DBY" and "WITH RECURSIVE AS ..." but it doesn't seem to solve my problem.
GIVEN TABLES:
Table A
+------+------------+----------+
| id | prev_id | date |
+------------------------------+
| 1 | | 20200101 |
| 23 | 1 | 20200104 |
| 34 | 23 | 20200112 |
| 41 | 34 | 20200130 |
+------------------------------+
Table B
+------+-----------+
| ref_id | key |
+------------------+
| 41 | abc |
+------------------+
(points always to the lates entry in table "A". Update, no history)
Join Statement:
SELECT
id, prev_id, key, date
FROM A
LEFT OUTER JOIN B ON B.ref_id = A.id
GIVEN psql result set:
+------+------------+----------+-----------+
| id | prev_id | key | date |
+------------------------------+-----------+
| 1 | | | 20200101 |
| 23 | 1 | | 20200104 |
| 34 | 23 | | 20200112 |
| 41 | 34 | abc | 20200130 |
+------------------------------+-----------+
DESIRED output:
+------+------------+----------+-----------+
| id | prev_id | key | date |
+------------------------------+-----------+
| 1 | | abc | 20200101 |
| 23 | 1 | abc | 20200104 |
| 34 | 23 | abc | 20200112 |
| 41 | 34 | abc | 20200130 |
+------------------------------+-----------+
The rows of the result set are connected by columns 'id' and 'prev_id'.
I want to calculate the "key" column in a reasonable time.
Keep in mind, this is a very simplified example. Normally there are a lot of more rows and different keys and id's
I understand that you want to bring the hierarchy of each row in tableb. Here is one approach using a recursive query:
with recursive cte as (
select a.id, a.prev_id, a.date, b.key
from tablea a
inner join tableb b on b.ref_id = a.id
union all
select a.id, a.prev_id, a.date, c.key
from cte c
inner join tablea a on a.id = c.prev_id
)
select * from cte
My table structure is as shown below
Id | Name | City | Country | State
01 | Bob | *NY* | null | null
01 | Bob | null | *US* | null
01 | Bob | null | null | *AL*
02 | Roy | *LA* | null | null
02 | Roy | null | *IN* | null
02 | Roy | null | null | *MG*
I want to generate two output records from the above table like below.
Id | Name | City |Country | State
01 | bob | NY | US | AL
02 | Roy | LA | IN | MG
You can use aggregation:
select id, name, max(city), max(country), max(state)
from t
group by id, name;
I have the following table in MS Access:
ID | column1 | column2 | column3
---+---------+-------------------+--------------
1 | A | Publishers | Publishers
2 | 01 | Commercial |
3 | 02 | University Press |
4 | B | Place | Place
5 | 01 | United States |
6 | 04 | Western Europe |
7 | 05 | Other |
8 | C | Language | Language
9 | 01 | English |
10 | 02 | French |
I am looking for the following result
ID |column1 | column2 | column3
---+---------+-------------------+--------------
1 | A | Publishers | Publishers
2 | 01 | Commercial | Publishers
3 | 02 | University Press | Publishers
4 | B | Place | Place
5 | 01 | United States | Place
6 | 04 | Western Europe | Place
7 | 05 | Other | Place
8 | C | Language | Language
9 | 01 | English | Language
10 | 02 | French | Language
So basically pulling down column3 heading. I have tried searching the net and asking other pals with some ms access knowledge. But really couldn't find any "pull down" query. Copy/paste wouldn't suffice as this will be performed many times in a day and with much larger data set. Can this be done without vba (looking to get this done through a query)?
If you have a column that specifies the ordering, you can do this with a correlated subquery:
select column1, column2,
(select top (1) t2.column3
from t as t2
where t2.id <= t.id and
t2.column3 is not null
order by t2.id desc
) as column3
from t;
I have the following table :
| RoomID | OrderID | Occupancy | Status |
+--------+---------+-----------+---------------+
| 01 | 101 | Vacant | inspection |
| 01 | 102 | Occupied | Preservation |
| 01 | 103 | Occupied | inspection |
| 01 | 104 | Vacant | inspection |
| 02 | 201 | Vacant | inspection |
| 02 | 202 | Occupied | inspection |
| 02 | 203 | Vacant | inspection |
| 03 | 301 | Vacant | inspection |
| 03 | 302 | Occupied | inspection |
| 03 | 303 | Occupied | Preservation |
| 03 | 304 | Occupied | Preservation |
| 04 | 401 | Occupied | inspection |
| 04 | 402 | Occupied | inspection |
| 04 | 403 | Vacant | Preservation |
| 04 | 404 | Occupied | inspection |
I need to pull my data on a RoomID level where the Occupancy = 'Occupied' and Status = 'Preservation' in any instance of a given RoomID.
The result should look like the following:
| RoomID | Flag |
+--------+---------+
| 01 | 1 |
| 02 | 0 |
| 03 | 1 |
| 04 | 0 |
I have an impression that this is easy but I cannot see it at the moment, thank you in advance for your help !
You can use conditional aggregation.
select roomid,
count(distinct case when Occupancy = 'Occupied' and Status = 'Preservation' then 1 end) flag
from tablename
group by roomid
You can also use the below query using UNION.
;with cte_1
AS
( SELECT DISTINCT RoomId
FROM YourTable
WHERE Occupancy='Occupied' AND Status='Predervation')
SELECT RoomId,1 Status
FROM cte_1
UNON
SELECT DISTINCT RoomId,0 Status
FROM YourTable t
WHERE NOT EXISTS(SELECT 1 FROM cte_1 c
WHERE t.RoomId=c.RoomId)