Oracle - Seis exemplos de junções - Six Examples of Joins
Exemplos de consultas SQL que usam junções para ajudá-lo a entender os conceitos de junção de tabelas Aprender como usar junções em SQL é um conceito útil. Você leu meu artigo sobre Joins que explica os diferentes tipos de joins com alguns exemplos. Mas e se você quiser escrever consultas mais complicadas? Em nossos trabalhos, geralmente fazemos mais do que apenas INNER JOINs entre duas tabelas. Neste guia, compartilharei alguns exemplos de junções mais complicadas, para ajudá-lo a entender quantas tabelas podem ser unidas.
Examples of SQL queries that use joins to help you understand the concepts of joining tables Learning how to use joins in SQL is a helpful concept. You’ve read my article on Joins that explains the different types of joins with some examples. But what if you want to write more complicated queries? In our jobs, we’re often doing more than just INNER JOINs between two tables. In this guide, I’ll share a few examples of more complicated joins, to help you understand how many tables can be joined together.
Este é o banco de dados de amostra que estamos usando. É uma loja online, que contém dados sobre os clientes do site (tabela user_account), seus pedidos e order_lines, os produtos, tabelas separadas para cada um de seus atributos (por exemplo, cor e tamanho), informações do fornecedor e pedidos para esses fornecedores. Aqui está o ERD:
This is the sample database we’re using. It’s an online store, which contains data about customers from the website (user_account table), their orders and order_lines, the products, separate tables for each of their attributes (e.g. colour and size), supplier information, and orders to those suppliers. Here’s the ERD:
Agora, vamos dar uma olhada em alguns exemplos de consultas que usam joins. Você notará que usei apelidos de tabela em todas as consultas. Embora os apelidos de tabela não sejam obrigatórios, usei-os porque são uma boa prática e facilitam a escrita de consultas.
Now, let’s take a look at some examples of queries that use joins. You’ll notice that I’ve used table aliases in all of the queries. While table aliases are not required, I’ve used them because they are good practice, and they make it easier to write queries.
Para este exemplo, queremos: Encontrar todos os pedidos e produtos e detalhes do pedido de um cliente. Para fazer isso, nossa consulta ficaria assim:
For this example, we want to: Find all orders and products and order details for a customer. To do this, our query would look like this:
SELECT co.order_id , co.username , co.shipping_address , co.billing_address , co.order_date , co.order_discount , col.order_line_id , col.qty , col.discount , col.price , p.product_id , p.product_name FROM customer_order co INNER JOIN customer_order_line col ON co.order_id = col.order_id INNER JOIN product p ON col.product_id = p.product_id WHERE co.username = ‘jsmith’;
Selecionei a maioria dos campos das três tabelas mencionadas. Isso dará uma saída que mostra muitas informações para os pedidos. Um INNER JOIN foi usado em todos os casos, porque não queremos ver pedidos sem linhas de pedido ou linhas de pedido sem produtos. Além disso, usei uma cláusula WHERE de “jsmith”, mas a ideia é que qualquer nome de usuário pode ser usado aqui.
I’ve selected most fields from the three tables mentioned. This will give an output that shows a lot of information for the orders. An INNER JOIN has been used in all cases, because we don’t want to see orders without order lines, or order lines without products. Also, I’ve used a WHERE clause of “jsmith” but the idea is that any username can be used here.
Para este exemplo, queremos: Encontrar o nome do usuário e todos os endereços que um usuário possui para sua conta. Isso pode ser feito com uma combinação das tabelas user_account, user_address e address.
For this example, we want to: Find the user’s name and all addresses that a user has for their account. This can be done with a combination of the user_account, user_address, and address tables.
SELECT u.username , u.first_name , u.last_name , a.address_id , a.address FROM user_account u INNER JOIN user_address ua ON u.username = ua.username INNER JOIN address a ON ua.address_id = a.address_id WHERE u.username = ‘jsmith’;
Estamos selecionando dados da tabela user_account e endereço. Não precisamos visualizar nenhum dado da tabela user_address, porque é apenas uma tabela de junção e ambos os campos estão armazenados em outro lugar. Além disso, como acima, estamos limitando o nome de usuário “jsmith”, mas pode ser alterado para qualquer nome de usuário necessário.
We’re selecting data from the user_account and address table. We don’t need to view any data from the user_address table, because that’s just a joining table and both of the fields there are stored elsewhere. Also, as above, we limiting on a username of “jsmith”, but this can be changed to whatever username is needed.
Queremos uma consulta que: Encontre todos os produtos e todos os seus atributos (categoria, marca, cor, fornecedor, tamanho). Nossa consulta ficaria assim:
We want a query that will: Find all products and all of their attributes (category, brand, colour, supplier, size). Our query would look like this:
SELECT p.product_id , p.product_name , pc.category_name , b.brand_name , c.colour_name , sz.size_name , su.supplier_name FROM product p INNER JOIN product_category pc ON p.product_category_id = pc.category_id INNER JOIN brand b ON p.brand_id = b.brand_id INNER JOIN colour c ON p.colour_id = c.colour_id INNER JOIN size sz ON p.size_id = sz.size_id INNER JOIN supplier su ON p.supplier_id = su.supplier_id;
Exibimos o nome de cada tabela e não o ID. Mas usamos o ID para cada junção da tabela. Existem junções da tabela de produtos para cinco outras tabelas, perfazendo um total de seis tabelas nesta consulta.
We’ve displayed the name from each table and not the ID. But we have used the ID for each table’s join. There are joins from the product table to five other tables, making six tables in this query in total.
Encontre todos os clientes, todos os pedidos que eles fizeram (se houver) e todos os produtos nesses pedidos. Nossa consulta ficaria assim:
Find all customers, any orders they have placed (if there are any), and all of the products on those orders. Our query would look like this:
SELECT u.username , u.first_name , u.last_name , co.order_id , co.order_date , co.order_discount , col.order_line_id , col.qty , col.discount , col.price , p.product_id , p.product_name FROM user_account u LEFT JOIN customer_order co ON u.username = co.username INNER JOIN customer_order_line col ON co.order_id = col.order_id INNER JOIN product p ON col.product_id = p.product_id;
Esta é a primeira consulta em que usamos LEFT JOIN. A razão para isso é que queríamos ver todos os clientes e todos os pedidos que eles fizeram (se houver). Queremos ver os clientes mesmo que eles não tenham pedidos. Se usarmos um INNER JOIN, estaremos eliminando todos os clientes que não têm pedidos. Portanto, usamos LEFT JOIN de user_account para customer_order, o que nos permite continuar mostrando as user_accounts que não têm registros correspondentes na tabela customer_order. As colunas da tabela customer_order serão mostradas como NULL para as linhas que não têm pedidos. Também fizemos um INNER JOIN para as outras duas tabelas - customer_order_line e product. Queremos ver todas as linhas de pedido e produtos, onde existe um pedido. Não há regra dizendo que precisamos ter o mesmo tipo de junção para cada tabela.
This is the first query we’ve used a LEFT JOIN on. The reason for this is that we wanted to see all customers, and any orders they have placed (if there are any). We want to see customers even if they don’t have any orders. If we used an INNER JOIN, we would be eliminating any customers that don’t have orders. So, we use a LEFT JOIN from user_account to customer_order, which allows us to keep showing the user_accounts that don’t have matching records in the customer_order table. The columns from the customer_order table will show as NULL for the rows that don’t have orders. We have also done an INNER JOIN for the other two tables - customer_order_line and product. We want to see all order lines and products, where an order exists. There’s no rule saying we need to have the same join type for each table.
Neste exemplo, queremos: Encontrar todos os produtos, todos os seus atributos e todos os pedidos que fizeram (se houver). Nossa consulta seria:
In this example, we want to: Find all products, all of their attributes, and any orders they have placed (if there are any). Our query would be:
SELECT p.product_id , p.product_name , pc.category_name , b.brand_name , c.colour_name , sz.size_name , su.supplier_name , co.order_id , co.order_date , col.order_line_id , col.qty FROM product p INNER JOIN product_category pc ON p.product_category_id = pc.category_id INNER JOIN brand b ON p.brand_id = b.brand_id INNER JOIN colour c ON p.colour_id = c.colour_id INNER JOIN size sz ON p.size_id = sz.size_id INNER JOIN supplier su ON p.supplier_id = su.supplier_id LEFT JOIN customer_order_line col ON p.product_id = col.product_id INNER JOIN customer_order co ON col.order_id = co.order_id;
Selecionamos nas tabelas de produtos e atributos, usando INNER JOINs, da mesma forma que fizemos anteriormente. No entanto, agora estamos ingressando em customer_order_line usando LEFT JOIN. Isso porque queremos mostrar todos os produtos, mesmo que não haja pedidos. Os produtos são unidos aos pedidos por meio da tabela customer_order_line, de modo que é onde fazemos a junção à esquerda. Fizemos um INNER JOIN para a tabela customer_order, pois não queremos mostrar pedidos sem linhas de pedido.
We have selected from the product and attribute tables, using INNER JOINs, in the same way as we did earlier. However, we’re now joining to the customer_order_line using a LEFT JOIN. This is because we want to show all products, even if there are no orders. The products are joined to orders through the customer_order_line table, so that’s where we do the left join. We have done an INNER JOIN to the customer_order table, as we don’t want to show orders without order lines.
Neste exemplo, queremos: Encontrar todos os produtos, seus fornecedores e quaisquer pedidos feitos a esses fornecedores e suas linhas de pedido. Nossa consulta ficaria assim:
In this example, we want to: Find all products, their suppliers, and any orders places with those suppliers and their order lines. Our query would look like this:
SELECT p.product_id , p.product_name , s.supplier_id , s.supplier_name , so.order_id , so.order_discount , sol.order_line_id , sol.qty , sol.discount , sol.price FROM product p INNER JOIN supplier s ON p.supplier_id = s.supplier_id LEFT JOIN supplier_order so ON so.supplier_id = s.supplier_id INNER JOIN supplier_order_line sol ON so.order_id = sol.order_id;
Isso mostra todos os produtos e seus fornecedores. Ele usa LEFT JOIN na tabela supplier_order, pois queremos ver todos os produtos e fornecedores, mesmo que não haja pedido para eles. Mesmo que a tabela supplier_order_line esteja associada à tabela de produtos, não juntamos essas tabelas lá. Se o fizéssemos, veríamos apenas as linhas de pedido do produto que estamos olhando. Não veríamos linhas de pedido para todo o pedido. Portanto, como você pode ver, podemos usar diferentes tipos de junções para obter dados de um banco de dados em qualquer estrutura que quisermos. Ter um banco de dados normalizado, com dados em tabelas diferentes, é fácil de manter. Podemos usar junções para obter todos os dados de que precisamos para relatórios ou aplicativos.
This shows all products and their suppliers. It uses a LEFT JOIN on the supplier_order table, as we want to see all products and suppliers even if there is no order for them. Even though the supplier_order_line table is joined to the product table, we haven’t joined those tables there. If we did, we would only see order lines for the product we’re looking at. We wouldn’t see order lines for the entire order. So, as you can see, we can use different types of joins to get data from a database in whatever structure we like. Having a normalised database, with data in different tables, is easy to maintain. We can use joins to get whatever data we need for reporting or applications.