postgres: left join by unknown table - column value - postgresql

I know this is a stupid question, but I'm gotta ask away.
I'm in a situation where the db I'm working on doesn't have a "backwards" relation to another table.
Let's say I have three tables - let's call them type tables, rt, wt, and ret.
Each of those tables has a group_id.
Each group table has type which may contain rt, wt, or ret.
The normal procedure for selection is select from a type table and then left join group on group_id.
I'm in a situation where I need to select in the reverse order, but I don't know which table I'm to be selecting from at run time. All I have is the type.
Is there such a thing as selecting a table by a column value? such as
SELECT * FROM group LEFT JOIN `group.type` ON `group.type`.group_id = group.id

In my case, I just did multiple left joins, of course only one of them stuck.

Related

Unexpected sort order on postgres left outer join

Background
I'm using Postgres 11 and pgAdmin4 v5.2. The problem I describe below is on my dev machine which has both the postgres server and pgAdmin client.
Questions I've looked at on SO that deal with incorrect ordering seem related to collation-related issues with ordering of text fields, whereas my problem is on an integer field.
Setup
I have a table norm_plans that contains ~5k records.
Column | Type
---------------------------------
canon_id | integer
name | character varying(200)
...
other fields
canon_id is autopopulated using a sequence.
I've created a new table norm_plans_cmp as a copy of norm_plans (CREATE TABLE norm_plans_cmp AS TABLE norm_plans WITH DATA;)
I next insert some new records into norm_plans and update some existing records (fields other than canon_id.
The new records increment the sequence and are assigned canon_id values as expected.
I now want to compare norm_plans against norm_plans_cmp so I perform a left outer join:
select a.*, b.*
from norm_plans a
left outer join norm_plans_cmp b
on a.canon_id = b.canon_id
order by a.canon_id
Problem
I would expect records to be sorted by canon_id. This holds true from 1-2000, but after 2,000 I get canon_ids from 5,001 to 5,111 (which is the last canon_id) and then it again picks up from 2,001. I'm viewing this data from pgAdmin, see screenshot 1 below showing the shift from 2,000 to 5,001, and screenshot 2 showing the transition again from 5,111 back to 2,001.
Additional observations
While incorrect, the ordering seems consistent. Running the query multiple times results in the same (incorrect) ordering.
Despite my question title, I'm not totally sure the left join has anything to do with this.
Running SELECT * ... ORDER BY canon_id on norm_plans or norm_plans_cmp alone also result in incorrect ordering, albeit at different points in the order.
Answers to this SO question suggest index corruption may be a contributing problem, but I have no indexes on either norm_plans or norm_plans_cmp (canon_id is not defined as a PK).
At this point, I'm stumped!

LEFT JOIN returns incorrect result in PostgreSQL

I have two tables: A (525,968 records) and B (517,831 records). I want to generate a table with all the rows from A and the matched records from B. Both tables has column "id" and column "year". The combination of id and year in table A is unique, but not in table B. So I wrote the following query:
SELECT
A.id,
A.year,
A.v1,
B.x1,
B.e1
FROM
A
LEFT JOIN B ON (A.id = B.id AND A.year = B.year);
I thought the result should contain the same total number of records in A, but it only returns about 517,950 records. I'm wondering what the possible cause may be.
Thanks!
First of all, I understand that this is an example, but postgres may hava an issues with capital letters in the table names.
Secondly, it may be a good idea to check how exactly you calculated 525,968 records. The thing is - if you use sime kind of client of database administration / queries - it may show you different / technical information about tables (there may be internal row counters in postgres that may actually differ from the number of records).
And finally to check yourself do something like
SELECT
count("A".id)
FROM
"A"

Postgresql get references from a dictionary

I'm trying to build a request to get the data from a table, but some of those columns have foreign keys I would like to replace by the associated keyword in one request.
Basically there's
table A with column 1:PKA-ID and column 2:name.
table B with column 1:PKB-ID, column 2:FKA-ID, column 3:amount.
I want to get all the lines in table B but with all foreign keys replaced by the associated names in table A.
I started building a request with a subrequest + alias to get that, but ofc I have more than one result per subrequest, yet I can't find a way to link that subrequest to the ID of table B [might be exhausted, dumb or both] from the main request. I did something like that:
SELECT (SELECT "NAME" FROM A JOIN B ON ID = FKA-ID) AS name, amount FROM TABLEB;
it feels so simple of a request yet...
You don't need a join in the subselect.
SELECT pkb_id,
(SELECT name FROM a WHERE a.pka_id = b.fka_id),
amount
FROM b;
(See it live in SQL Fiddle).
The subselect query runs for each and every row of its parent select and has the parent row available from the context.
You can also use a simple join.
SELECT b.pkb_id, a.name, b.amount
FROM b, a
WHERE a.pka_id = b.fka_id;
Note that the join version puts less restrictions on the PostgreSQL query optimizer so in some cases the join version might work faster. (For example, in PostgreSQL 9.6 the join might utilize multiple CPU units, cf. Parallel Query).

Left joining right aligned field with left aligned field in Crystal

I have a report where I need to join two tables but the fields are defined differently between them and I cannot change the table schemas because its JDEdwards. So I have one field as 30 characters left aligned and another another as 12 characters right aligned. The values will always be under 12 characters. So the issue is not the difference in size but the alignment/padding. I have to do a left join though. Right now the report is just comparing in the data selection and causing an inner join. But I need to change it to left join to stop losing rows. Is there any way to do it?
What happens is when I create the link to do the left join in Database Expert, I end up getting the data from the joined table all blank due to it not finding any rows because of the padding difference.
Since you only need one value from the table to be joined you can instead create a single SQL Expression to get the value for you without the need to add any tables to the report itself via Database Expert. You'll be able to use any valid SQL so you can do pretty much whatever you want without being constrained by Crystal.
For example, say your report consists of Table_A with a foreign key that is 30-characters left-aligned and you're trying to join to Table_B to get at some field, but that key is 12 characters right-aligned. A simple example in Oracle would be something like this:
case when "Table_A"."ForeignKey" is null then null
else
(select Table_B.SomeFieldYouWant
from Table_B
where rpad(Table_B.PrimaryKey,30,'0')="Table_A"."ForeignKey"
end
It's important to note that in a SQL Expression, any fields referenced with double quotes means that it's referring back to tables/fields in your report instead of new tables in the subquery; this is how you relate the subquery back to your report's data.

sql query to retrieve DISTINCT rows on left join

I am developing a t-sql query to return left join of two tables, but when I just select records from Table A, it gives me only 2 records. The problem though is when I left join it Table B, it gives me 4 records. How can I reduce this to just 2 records?
One problem though is that I am only aware of one PK/FK to link these two tables.
The field you are using for the join must exist more than once in table B - this is why multiple rows are being returned in the join. In order to reduce the row count you will have to either add further fields to the join, or add a where clause to filter out rows not required.
Alternatively you could use a GROUP BY statement to group the rows up, but this may not be what you need.
Remember that the left join brings you null fields from joined table.
Also you can use select(distinct), but i can't see well you issue. Can you give us more details?