SQL Tables with no direct relation - postgresql

I have a PostgreSQL DB and I need to build a query to retrieve the information from a table that has no direct link with the main one.
The client is linked to the client_identity_document through its UUID and client_identity_document to the identity_document through the uuid_identity_document. I know I have to make an inner join, but I just started with relational databases and I don't know exactly the syntax to join tables that don't have direct relation.

try this
select *
from client c
inner join client_identity_document cid on c.UUID = cid.UUID_Client
inner join identity_document id on cid.uuid_identity_document = id.UUID

Related

SQL Natural Join

Okay. So the question that I got asked by the teacher was this:
(5 marks) Construct a SQL query on the dvdrental database that uses a natural join of two or more tables and an additional where condition. (E.g. find the titles of films rented by a particular customer.) Note the hints on the course news page if your query returns nothing.
Here is the layout of the database im working with:
http://www.postgresqltutorial.com/wp-content/uploads/2013/05/PostgreSQL-Sample-Database.png
The hint to us was this:
PostgreSQL hint:
If a natural join doesn't produce any results in the dvdrental DB, it is because many tables have the last update: timestamp field, and thus the natural join tries to join on that field as well as the intended field.
e.g.
select *
from film natural join inventory;
does not work because of this - it produces an empty table (no results).
Instead, use
select *
from film, inventory
where film.film_id = inventory.film_id;
This is what I did:
select *
from film, customer
where film.film_id = customer.customer_id;
The problem is I cannot get a particular customer.
I tried doing customer_id = 2; but it returns a error.
Really need help!
Well, it seems that you would like to join two tables that have no direct relation with each other, there's your issue:
where film.film_id = customer.customer_id
To find which films are rented by which customer you would have to join customer table with rental, then with inventory and finally with film.
The task description states
Construct a SQL query on the dvdrental database that uses a natural join of two or more tables and an additional where condition.quote

(JPA) Append condition in ON clause during Joins

I need the JPQL in this format:
SELECT *
FROM Person p
LEFT JOIN Address a ON p.id = a.id AND a.flat = 100;
But when i run the code the query being slightly modified henceforth the output of data changed..
SELECT * FROM Person p LEFT JOIN Address a ON p.id = a.id where a.flat = 100;
I suppose you want to format the sql output.
So for hibernate, you can set hibernate.format_sql=true to well format the sql.
If you are using spring boot, you can config it via spring.jpa.properties.hibernate.format_sql=true simply.
JPQL does not allow joining to arbitrary other root objects, so you can't do that in JPQL; only allowing you to join along relations. Individual vendors may offer a vendor extension to allow joining across arbitrary roots but you then lose portability.
To provide more than that you have to post the actual JPA entities, and you haven't.

zf many to many relationship, how to find values stored in intermediary table without a second lookup

I have a many to many relationship between two tables which is represented with an intermediary table. I am using the ZF1 table relationships methodology to model the database in my application and this works fine. One thing I am struggling with is to pull data from the intermediary table when performing a many to many lookup. For exmaple:
productsTable
product_id,
product_name
customerTable
customer_id,
customer_name
salesTable
customer_id,
product_id,
date_of_sale
In this case where the sales table is the intermediary table and the many to many relationship is between customers and products. I add the referenceMap to the sales table model for products and customers and the dependent table "sales" to the product table model and the customer table model.
I can then successfully use the following code to get all the products for a given customer (or vice-versa).
$productTable = new productsTable();
$product = $productTable->find(1)->current();
$customers = $product->findManyToManyRowset('customerTable','salesTable');
But it does not include the "date_of_sale" value in the rowset returned. Is there a way of including the values from the intermediary table without doint a separate database lookup. Ican't see anything in the zf docs.
Any help would be cool.
I hope to eventually replace the zend_table with a datamapper implementation as it seems highly inefficient in terms of the number of db queries it executes which could be hugely reduced with slightly more complex SQL join queries rather than multiple simple selects but for now I'm stuck with this.
Thanks.
You can use JOIN queries in your code to make it in one call. From what I understand, you want to build this query
SELECT p.*, c.*, s.date_of_sale FROM sales AS s
INNER JOIN products AS p ON p.product_id = s.product_id
INNER JOIN customers AS c ON c.customer_id = s.customer_id
WHERE p.product_id = '1';
To achieve this, you can refer to Complex SQL query into Zend to see how I translate it to a Zend_Db Query or just use something like
$select = $this->select()->setIntegrityCheck(false);
$select->from(array('s'=>'sales'), array('date_of_sale'));
$select->join(array('p'=>'products'), 'p.product_id = s.product_id', '*');
$select->join(array('c'=>'customers'), 'c.customer_id = s.customer_id', '*');
$select->where('p.product_id = '.$productId);
Obviously, it would be better to quoteInto the where clause but I'm just too lazy.
Hope this helps !

Getting a list of tables that a view/table depends on in PostgreSQL

In PostgreSQL, is there a way to get all of the tables that a view/table depends on based on its use of foreign keys and access to a given table?
Basically, I want to be able to copy the structure of a view/table using a script and want to be able to automatically get the list of tables that I would also need to copy in order for everything to still work right.
This response appears to be headed in the right direction, but doesn't give me the results that I expect/need. Any suggestions?
Using the info from Andy Lester, I was able to come up with the following queries to retrieve the information that I needed.
Get Tables that Foreign Keys refer to:
SELECT cl2.relname AS ref_table
FROM pg_constraint as co
JOIN pg_class AS cl1 ON co.conrelid=cl1.oid
JOIN pg_class AS cl2 ON co.confrelid=cl2.oid
WHERE co.contype='f' AND cl1.relname='TABLENAME'
ORDER BY cl2.relname;
Get Tables that a View or Rules from a Table refer to:
SELECT cl_d.relname AS ref_table
FROM pg_rewrite AS r
JOIN pg_class AS cl_r ON r.ev_class=cl_r.oid
JOIN pg_depend AS d ON r.oid=d.objid
JOIN pg_class AS cl_d ON d.refobjid=cl_d.oid
WHERE cl_d.relkind IN ('r','v') AND cl_r.relname='TABLENAME'
GROUP BY cl_d.relname
ORDER BY cl_d.relname;
Assuming you have your foreign keys set up correctly, use pg_dump to dump the table definitions.
pg_dump -s -t TABLENAME
I think it is a quite bad idea. Just copy the whole database, I think that the application wants to have all data, not only data from one table.
What's more, there are also triggers, that could depend on some tables, but to know that you'd have to make not so easy code analysis.
In psql, adding + to the usual \d gives you a "Referenced by" list along with the table definition.
\d+ tablename

How can I write a SQL select statement to include a lookup from another table?

I'm copying data from one database to another and massaging the data while I'm at it. Both databases have tables called Clients and Jobs.
However, in database "Alpha" the Jobs table does not have a relationship to the Clients table, where database "Epsilon" does. Alpha's Jobs table just has the Clients name in an nvarchar column.
I need a select statement to lookup the Client's ID in the Client table by their name while I am inserting it into the Jobs table in Epsilon.
My unfinished SQL statement looks like this:
insert into Epsilon.dbo.Jobs (ClientId, Name, Location, DateCreated)
select ????, Name, Location, DateCreated from Alpha.dbo.Jobs
How can I modify this so that the ???? contains the ClientId from the Clients table in Epsilon? I know I need to lookup the data using the Name column in Jobs, but I can't figure out the syntax for this.
What you need is a join. Joins, contrary to what pretty much everybody thinks when starting out, don't require defined relationships in the schema of the database. They just require that the two columns you're comparing have the same type (edit see comments).
The question is which join do you want. Because there isn't a relationship defined, there may be clients that have jobs and clients that don't, and jobs that have clients and jobs that don't.
I'm assuming that you want all JOBS that exist, and where a ClientId matches the CLIENTS table bring in the ClientId, and where that relationship doesn't exist to leave the ClientId null. We can do this with a LEFT JOIN. Jobs LEFT JOIN Clients will bring in all records on the LEFT, even where the relationship defined with Clients on the right doesn't exist. We could reverse the two and do a RIGHT JOIN, but that's not what people usually do. I'll leave it to you to read up on other types of joins and how they work.
So your select statement would look like:
select ClientId, Name, Location, DateCreated
from Alpha.dbo.Jobs as J LEFT JOIN
Alpha.dbo.Clients as C ON j.ClientName = c.ClientName
If Jobs.ClientName is not the same data type as c.ClientName, you can edit the schema before running the query to bring them in line with each other.
insert into Epsilon.dbo.Jobs (ClientId, Name, Location, DateCreated)
select c.ClientID, a.Name, a.Location, a.DateCreated from Alpha.dbo.Jobs a
join Epsilon.dbo.Client c on c.Name = a.ClientName
This is a pretty optimistic join, but even if it needs to be modified this should give you the general idea.
insert into Epsilon.dbo.Jobs
(ClientId, Name, Location,
DateCreated)
select c.ClientId, Name, Location, DateCreated from Alpha.dbo.Jobs as j
inner join Epsilon.dbo.Clients as c On
(j.ClientId = c.ClientId)