Concepts / Retrieving Data with SELECT

Retrieving Data with SELECT

INSERT adds new rows to a table; specify the table, columns, and values.

  • Programming

From Stored Rows to Useful Results

A database becomes useful when a program can retrieve exactly the information it needs. SELECT is the SQL command for retrieving rows and columns from a table. Instead of loading an entire table into your program, you can choose particular columns, filter rows with WHERE, and sort the results with ORDER BY. Python receives the result through a cursor and can process each returned row one at a time.

The central path is: SELECT defines the requested data, WHERE reduces the rows, ORDER BY arranges them, the cursor supplies them on demand, and the Python loop processes them.

The SELECT Pipeline

filter rowschoose columnssort resultsTrack tableall rows and columnsWHEREmatching rowsSELECT title, playschosen columnsORDER BY playssorted result
How does a SELECT query filter rows, choose columns, and sort the resulting data?

A SELECT statement has three essential ideas: the columns to retrieve, the table to retrieve them from, and the rows to include. The basic structure is SELECT columns FROM table. WHERE is optional and restricts the result to rows matching a condition. ORDER BY is also optional and sorts the returned rows by one or more columns, in ascending or descending order.

sql

In this example, the database considers rows in Track, keeps only rows whose plays value is greater than 100, returns only title and plays, and sorts those results from higher plays to lower plays. The asterisk can be used when every column is needed, as in SELECT * FROM Track WHERE title = 'My Way'. Listing columns is more precise when the program needs only part of each row.

Rows Inside the Cursor

fetch next rowloop iterationfetch next rowloop iterationSELECT resultcursorrow 1('Song A', 240)process rowtitle and playsrow 2('Song B', 180)process rowtitle and plays
How does each row move from the database cursor into the Python loop, and what happens on each iteration?

Executing SELECT produces a cursor, which is a pointer to the result set. The cursor does not immediately place every matching row into memory. When a Python for loop advances through the cursor, the cursor supplies the next row. This on-demand behavior lets a program begin processing immediately and keeps memory usage low even when a result set is large.

cursor = connection.execute( "SELECT title, plays FROM Track ORDER BY plays DESC" ) for row in cursor: title, plays = row print(title, plays)

Tuple Positions and Selected Columns

position 0position 1titleSong Arow[0]Song Aplays240row[1]240
How do tuple positions map to the selected database columns in each returned row?

A returned database row is a Python tuple. Its values are ordered from left to right according to the columns in the SELECT list. If the query selects title and plays, row[0] is the title and row[1] is the plays value.

python

The same tuple can be handled with tuple unpacking, as in title, plays = row. Index access is useful when you need one position directly; unpacking makes the intended column names clearer. The important rule is that the positions follow the order of the SELECT statement, not necessarily the physical order of columns in the table.

Safe Values and Saved Changes

ApproachHow values are suppliedResult
Parameterized queryQuestion marks in SQL and a tuple passed separatelySQL command and data remain separate
String concatenationValues are joined directly into the SQL textData can alter the meaning of the command
python

The first argument to execute is the SQL command with question-mark placeholders. The second argument is a tuple containing the actual values. The database driver matches each question mark with the corresponding tuple value in order. This keeps the command separate from its data and prevents SQL injection, in which crafted data could alter the meaning of the SQL command. Use this pattern for dynamic INSERT, UPDATE, DELETE, or SELECT values.

A Complete Retrieval Check

Insert, commit, then retrieve

Add a Track row and verify it with a SELECT query.

Insert: Use question-mark placeholders and pass the title and plays values in a tuple.

Commit: Call commit() so the inserted row is finalized and written permanently to disk.

Select: Retrieve title and plays for rows whose plays value is greater than 100, sorting from highest to lowest.

Iterate: Loop through the cursor. Each iteration receives one tuple whose first value is title and second value is plays.

The program verifies the inserted data while processing rows one at a time through the cursor.

python

The INSERT uses a parameterized query, and commit() makes the change persistent. The SELECT also uses a parameterized value for the WHERE condition. The cursor then supplies matching rows in descending plays order. If the inserted row meets the condition, it appears in the loop's output. Using SELECT after an INSERT is a practical way to check whether the insertion and commit worked correctly.

Mistakes That Hide Retrieval Problems

  • Building SQL by concatenating dynamic values

    Crafted data could change the meaning of the SQL command and create a SQL injection vulnerability.

    Fix: Use question-mark placeholders and pass the values separately in a tuple.

  • Forgetting to call commit() after INSERT

    The changes may be lost if the program crashes or the connection closes unexpectedly before the transaction is finalized.

    Fix: Call commit() after the changes that should be persisted.

  • Assuming a returned row is a dictionary

    The source model returns each row as a tuple whose positions follow the SELECT column order.

    Fix: Use index access such as row[0], or unpack the tuple into variables.

  • Loading every result before processing it

    Putting all rows into memory can be inefficient for large results.

    Fix: Iterate through the cursor directly so rows are fetched on demand.

  • Sorting retrieved rows in Python when SQL can sort them

    The database can often sort more efficiently, especially for large result sets.

    Fix: Use ORDER BY in the SELECT statement.

Practice the Retrieval Path

MEDIUM

Write a Python database operation that selects title and plays from Track where plays is greater than a supplied value, orders the results by plays in descending order, and prints each row by unpacking the cursor result. Use a question-mark placeholder for the supplied value.

Hints
  • Put title and plays in the SELECT list.
  • Place the condition in a WHERE clause and the sorting instruction in ORDER BY.
  • Pass the threshold as a one-value tuple and iterate directly through the cursor.
  1. SELECT retrieves database data by combining a column list, a table name, and optional WHERE and ORDER BY clauses. Executing SELECT produces a cursor, and a Python for loop obtains rows from that cursor on demand. Every returned row is a tuple whose positions match the order of the selected columns. For dynamic values, parameterized queries keep SQL commands separate from data. When adding rows with INSERT, call commit() to finalize the transaction and persist the changes.

Key Takeaways

  • Use SELECT to choose columns and retrieve rows from a table.
  • Use WHERE to filter rows and ORDER BY to sort the result.
  • A cursor supplies rows on demand, so direct iteration avoids loading the entire result set into memory.
  • Each returned row is a Python tuple ordered according to the SELECT statement.
  • Use parameterized queries for dynamic values, and call commit() after INSERT to persist changes.