How to view table relation in PostgreSQL Server? - java

How to view table relation in PostgreSQL server?
I have tried several times and more than 2 years ago to find table relation in PostgreSQL server but couldn't get any help.
So are there any way to find table relation same in SQL server or Access? Or is it possible to view table relation in PostgreSQL server?

If you want to list all the relationships that start from a table, you must search the foreign keys.
In Postgresql it means to search for constraints.
It is solved in this other question:
SQL to list table foreign keys
From the answer:
SELECT
tc.constraint_name, tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='mytable';

You could try using a UI like DataGrip or pgAdmin. I use DataGrip on my Postgres apps. You may simply try using the postgres interactive shell -- psql.
Best of luck

I know this question is not exactly about that, but I think lots of people land here looking for an easy way to see the relationships between tables using different data types (like parent id with bigint and child foreign key int, and vice versa).
Here's a quick way to spot all the columns with different types between parents and child tables:
SELECT
tc.constraint_name, tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name,
cf.data_type AS child_data_type,
cp.data_type AS parent_data_type
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
JOIN information_schema.tables as t
on t.table_name = tc.table_name and t.table_catalog = tc.table_catalog and t.table_schema = tc.table_schema
JOIN information_schema.columns as cf
on cf.table_name = tc.table_name and cf.column_name = kcu.column_name and cf.table_catalog = tc.table_catalog and cf.table_schema = tc.table_schema
JOIN information_schema.columns as cp
on cp.table_name = ccu.table_name and cp.column_name = ccu.column_name and cp.table_catalog = ccu.table_catalog and cp.table_schema = ccu.table_schema
WHERE constraint_type = 'FOREIGN KEY'
and cf.data_type <> cp.data_type;
Enjoy!

Related

criteria API predicate: group by on one column, find row min on another and then return third

I've got table
CREATE TABLE stp2_vehicles.can_data (
id bigserial NOT NULL,
receive_time timestamp NOT NULL,
gps_frame_id int8 NULL
);
based on it I need to add criteria predicate required for bigger query.
What i need in where clausule is select returning ids of can_data - only one id for each gps frame the one with earliest timestamp.
So in sql it would look like this:
select cd.id
from stp2_vehicles.can_data cd
right join
(select gps_frame_id, min(receive_time) as min_time
from stp2_vehicles.can_data
group by gps_frame_id
) cd2 on cd.gps_frame_id = cd2.gps_frame_id and cd.receive_time = cd2.min_time
;
unfortunately criteria api doesn't support joining with result of subquery.
I've tried also approach with self join (should be supported by criteria api) but solution I came with seems too computationally complex or has errors I can't see:
select cd.id
from stp2_vehicles.can_data cd
inner join stp2_vehicles.can_data cd2 on cd.id=cd2.id
where cd.receive_time = (select min(receive_time) from stp2_vehicles.can_data cd3 where cd.gps_frame_id = cd3.gps_frame_id );
By the way:
I've managed to solve simpler case:
select min(cd.id) from can_data cd group by cd.gps_frame_id
CriteriaQuery<CANData> criteriaQueryCanData = cb.createQuery(CANData.class);
Subquery<Long> subquery = criteriaQueryCanData.subquery(Long.class);
Root<CANData> canDataSubRoot = subquery.from(CANData.class);
subquery
.select(cb.least(canDataSubRoot.<Long>get(CANData_.ID)))
.groupBy(canDataSubRoot.<Long>get(CANData_.GPS_FRAME));
Since the subquery seems to be "static", you can define an entity for the result of the subquery by using the #Subselect annotation.

How do I Join two tables together in SQLite that can be used in JAVA Sprint Boot?

I am using a Movie Database that will link to the front-end of my website. i am using Java Spring Boot to link the Database. My question is, How can i join a Movies table and Reviews table>]?
try {
String getAllActorsbyMoviesidQuery = "SELECT * FROM tblMovies JOIN tblReviews ON tblReviews.actor_id = tblMovies.actor_id";
statement = dbConnection.createStatement();
ResultSet resultSet = statement.executeQuery(getAllReviewsbyMoviesidQuery);
Joining the 2 tables on actor_id is not probably the suitable way.
I guess there exists inside tblReviews a column like movie_id that refers to the id column of the table tblMovies:
SELECT * FROM tblMovies JOIN tblReviews ON tblReviews.movie_id = tblMovies.id
change the column names to the actual ones.
If you want the reviews for a particular movie, then add a WHERE clause, like:
WHERE tblMovies.id = ?
or
WHERE tblMovies.title = ?

JPA Join with aggregate function

I am a beginner when it comes to JPA and I am struggling to write the proper entity classes for my database structure.
Firstly, here are my tables:
create table article (
id varchar(100) not null primary key,
title varchar(255) not null
)
create table article_provider (
providerId varchar(60) not null,
articleId varchar(100) null,
isOnSale BOOL NOT NULL,
constraint article_provider_articleid_fk foreign key (articleId) references article (id) on update cascade on delete cascade
)
As you can see I have a one-to-many relationship (every article can have 0..n providers).
Now when accessing articles I would also like to know, if the article is on sale by any of it's providers. For this I would use the following SQL query:
SELECT article.*, MAX(article_provider.isOnSale) AS isOnSale FROM article
LEFT JOIN article_provider ON article.id = article_provider.articleId
GROUP BY article.id
How would I best go about fetching this type of result using Hibernate/JPA?
Your query is not right -- you use attributes in SELECT clause that are not in GROUP BY clause, but for example to select Article.id + MAX(whatever) you can use something like:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Article> query = builder.createQuery(Article.class);
Root<Article> root = query.from(Article.class);
Join<Article, ArticleProvider> join = root.join(Article_.provider, JoinType.LEFT);
query.multiselect(root.get(Article_.id), builder.max(sale));
query.groupBy(root.get(Article_.id));
// query will return collection of scalar attributes (ID + Number)
Object result = entityManager.createQuery(query).getResultList()
To select exactly Article.* + MAX(sales) you would need to use the above as a subquery and join again with Article entity.
But there are simillar of examples elsewhere: How do I write a MAX query with a where clause in JPA 2.0?
EDIT:
another tip: https://www.thoughts-on-java.org/hibernate-tip-subquery-criteriaquery/
correction/clarification: I have only assumed you want to use Criteria API where subquery and combining the results for Hibernate is probably the only way. But you may try to use JPA query language and/or different provider where subquery with multiple results can be used -- jpa eclipselink subquery in from clause

Partial export of db tables according to a select on master table

to accomodate testing in a large batch system I would like to have the possibility to export data from many tables that are all in a "master - detail" relationship, i.e. they are connected via foreign keys. I know I can do that programmatically via DBUnit for example.
Is there any framework / utility / tool for which I can just define the tabel relationships (e.g. table a is master for table b via foreign key b.1 and table c via foreign key c.1) and then give a condition for the master table (... where a.attribute = 'someCriteria') and the tool exports all connected data and lets me import the data on another database (thus I have a consistent subset of data of the source tables).
Any hints are appreciated. Thx.
You would use Jailer, a tool that do exactly what you need.
It has a GUI and a command line utilty.
If the tool you use to browse your database is able to export results of a query, you just have to execute the result of three queries:
select c.* from C c inner join A a on c.aId = a.aId where a.attribute = '...';
select b.* from B b inner join A a on b.aId = a.aId where a.attribute = '...';
select a.* from A a where a.attribute = '...';

Java: Hibernate - Query to delete from multiple tables

I have two tables connected by a foreign key with a one to many relation.
In entity A I have the following:
#org.hibernate.annotations.Cascade( {
org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
#OneToMany(mappedBy="monitoredFlight", fetch = FetchType.LAZY)
#OnDelete(action=OnDeleteAction.CASCADE)
private List<bTable> BTable = new ArrayList<BTable>();
Now I try to delete from table A with a bulk delete query:
Query query = em.createQuery("delete from A where originDateTime<:date");
and I get the foreign key constraint error. I decided to do the delete with a join just as I would in mysql, so I changed it to:
Query query = em.createQuery("delete from A join BTable where originDateTime<:date");
and I got a syntax error. I have tried several combination with or without join and nothing works; any ideas?
I am using mysql for the database and java for the language.
You can use a native query, the following should work in mysql:
delete a , b from a inner join b on a.id=b.a_id where ...
You can setup a foreign key with the parameter on delete cascade so that when the key it references is deleted all rows that it is a foreign key on are also deleted.

Categories

Resources