• Tidak ada hasil yang ditemukan

A Digression: Setting the Right ID

Dalam dokumen Buku Learning MySQL and MariaDB (Halaman 134-137)

Our INSERT from the previous section helped me fill my table with data I took from a free database, but it’s still missing data: the bird order for each bird. I defined my own orders of birds in the bird_orders table, giving each order an arbitrary order_id. However, the Cornell data had nothing to do with the numbers assigned when I created my bird_orders

table. So now I need to set the value of the order_id column to the right order_id from the bird_orders table — and to figure out that value, I have to find the order in the

cornell_bird_order column.

This is a bit complicated, but I am showing my process here to illustrate the power of relational databases. Basically, I’ll join my own bird_orders table to the data I got from Cornell. I loaded the bird orders from Cornell into a cornell_bird_order field. I have the exact same orders in the scientific_name field of my bird_orders table. But I don’t want to use the scientific name itself when I label each individual bird: instead, I want a number (an order_id) to assign to that bird.

I need to set the value of the order_id column to the right order_id from the

bird_orders table. To figure out that value, I have to find the order in the

cornell_bird_order column.

For that, I’ll use the UPDATE statement. Before I change any data with UPDATE, though, I’ll construct a SELECT statement for testing. I want to make sure my orders properly match up with Cornell’s. So I’ll enter this on my server:

SELECT DISTINCT bird_orders.order_id, cornell_bird_order AS "Cornell's Order", bird_orders.scientific_name AS 'My Order' FROM bird_families, bird_orders

WHERE bird_families.order_id IS NULL

AND cornell_bird_order = bird_orders.scientific_name LIMIT 5;

+---+---+---+

| order_id | Cornell's Order | My Order | +---+---+---+

| 120 | Struthioniformes | Struthioniformes |

| 121 | Tinamiformes | Tinamiformes |

| 100 | Anseriformes | Anseriformes |

| 101 | Galliformes | Galliformes |

| 104 | Podicipediformes | Podicipediformes | +---+---+---+

We’re testing a WHERE clause here that we’ll use later when updating our bird_families

table. It’s worth looking at what a WHERE clause give us before we put all our trust in it and

use it in an UPDATE statement.

This WHERE clause contains two conditions. First, it changes the bird_families table only where the order_id hasn’t been set yet. That’s kind of a sanity check. If I already set the

order_id field, there is no reason to change it.

After the AND comes the second condition, which is more important. I want to find the row in my bird_orders table that has the right scientific name, the scientific name assigned by Cornell. So I check where cornell_bird_order equals the scientific_name in the

bird_orders table.

This shows how, if you want to change data with INSERT…SELECT, REPLACE, or UPDATE, you can test your WHERE clause first with a SELECT statement. If this statement returns the rows you want and the data looks good, you can then use the same WHERE clause with one of the other SQL statements to change data.

The SELECT statement just shown is similar to the one we executed in the previous section of this chapter when we queried the birds, bird_families, and bird_orders tables in the same SQL statement. There is, however, an extra option added to this statement: the

DISTINCT option. This selects only rows in which all of the columns are distinct.

Otherwise, because more than five bird families are members of the Struthioniformes order, and I limited the results to five rows (i.e., LIMIT 5), we would see the first row repeated five times. Adding the DISTINCT flag returns five distinct permutations and is thereby more reassuring that the WHERE clause is correct.

Because the results look good, I’ll use the UPDATE statement to update the data in the

bird_families table. With this statement, you can change or update rows of data. The basic syntax is to name the table you want to update and use the SET clause to set the value of each column. This is like the syntax for the SELECT statement in Inserting Emphatically.

Use the WHERE clause you tested to tell MySQL which rows to change:

UPDATE bird_families, bird_orders

SET bird_families.order_id = bird_orders.order_id WHERE bird_families.order_id IS NULL

AND cornell_bird_order = bird_orders.scientific_name;

This is fairly complicated, so let’s reiterate what’s happening here: the UPDATE statement tells MySQL to set the order_id in the bird_families table to the value of the order_id of the corresponding row in the bird_orders table — but thanks to the AND clause, I do the update only where the cornell_bird_order equals the scientific_name in the

bird_orders table.

That’s plenty to take in, I know. We’ll cover this statement in more detail in Chapter 8.

Let’s see the results now. We’ll execute the same SQL statement we did earlier, but limit it to four rows this time to see a bit more:

SELECT * FROM bird_families ORDER BY family_id DESC LIMIT 4;

+---+---+---+---+

| family_id | scientific_name | brief_description | order_id | +---+---+---+---+

| 330 | Viduidae | Indigobirds | 128 |

| 329 | Estrildidae | Waxbills and Allies | 128 |

| 328 | Ploceidae | Weavers and Allies | 128 |

| 327 | Passeridae | Old World Sparrows | 128 | +---+---+---+---+

That seems to have worked. The order_id column for the Viduidae bird family now has a value other than NULL. Let’s check the bird_orders to see whether that’s the correct value:

SELECT * FROM bird_orders WHERE order_id = 128;

+---+---+---+---+

| order_id | scientific_name | brief_description | order_image | +---+---+---+---+

| 128 | Passeriformes | Passerines | NULL | +---+---+---+---+

That’s correct. The order_id of 128 is for Passeriformes, which is what the Cornell table said is the order of the Viduidae family. Let’s see whether any rows in bird_families are missing the order_id:

SELECT family_id, scientific_name, brief_description FROM bird_families

WHERE order_id IS NULL;

+---+---+---+

| family_id | scientific_name | brief_description | +---+---+---+

| 136 | Fregatidae | Frigatebirds |

| 137 | Sulidae | Boobies and Gannets |

| 138 | Phalacrocoracidae | Cormorants and Shags |

| 139 | Anhingidae | Anhingas |

| 145 | Cathartidae | New World Vultures |

| 146 | Sagittariidae | Secretary-bird |

| 147 | Pandionidae | Osprey |

| 148 | Otididae | Bustards |

| 149 | Mesitornithidae | Mesites |

| 150 | Rhynochetidae | Kagu |

| 151 | Eurypygidae | Sunbittern |

| 172 | Pteroclidae | Sandgrouse |

| 199 | Bucconidae | Puffbirds |

| 200 | Galbulidae | Jacamars |

| 207 | Cariamidae | Seriemas | +---+---+---+

For some reason, the data didn’t match the 15 rows in the bird_orders table. I had to determine why these didn’t match. Let’s look at how I resolved a couple of them.

I looked up the name of the order to which the Osprey belongs and found that there are two possible names: Accipitriformes and Falconiformes. Cornell used the Accipitriformes, whereas my bird_orders table has the Falconiformes (i.e., order_id 112). I’ll use that one and update the bird_families table:

UPDATE bird_families SET order_id = 112

WHERE cornell_bird_order = 'Accipitriformes';

I could have used the family_id in the WHERE clause, but by doing what I did here, I discovered two more bird families that are in the Accipitriformes order and updated all three in one SQL statement. Digging some more, I found that four of these bird families are part of a new order called Suliformes. So I added that order to the bird_orders table and then updated the rows for those families in the bird_families table. This method of clean-up is common when creating a database or when importing large amounts of data from another database.

Next, I’ll do some clean-up by dropping the extra column I added (cornell_bird_order) to the bird_families table and the cornell_birds_families_orders table:

ALTER TABLE bird_families

DROP COLUMN cornell_bird_order;

DROP TABLE cornell_birds_families_orders;

That set of examples was complicated, so don’t be discouraged if you were confused by it.

In time, you will be constructing more complex SQL statements on your own. In fact, you will come to look at what I did here and realize that I could have performed the same tasks in fewer steps. For now, I wanted to show you the power of MySQL and MariaDB, as well as their communities. I mention the communities because in the MySQL and MariaDB communities, you can sometimes find tables with data like this that you can download for free and then manipulate for your own use, thus saving you plenty of work and taking some of the ever pesky tediousness out of database management. There are other methods for bulk importing data, even when it’s not in a MySQL table. They’re covered in

Chapter 15.

Dalam dokumen Buku Learning MySQL and MariaDB (Halaman 134-137)