Reputation: 5326
How do I create a query that display every parent with its children rather than to display all parents first then children. For example, right now, the mySQL table shows all COMPUTERS and then DRIVES. I want it to display for every computer, display the drives associated with that computer. I.E.:
COMPUTER DRIVE PID ID
dell 1
apple 2
apple 3
hp 4
hp 5
WD300FV 1
WD440GB 1
WD55 2
WD44X 2...
I want it displayed like this where every computer is shown a list of its drives:
COMPUTER DRIVE PID
dell 1
WD300FV 1
WD440GB 1
apple 2
WD55 2
WD44X 2
apple 3.....
Where computer has a parent ID and drive has an ID.
When I do this query SELECT * FROM table
it doesn't create rows as I would like it to be displayed. I want every row that shows a computer to display a list of drives below the computer row.
Upvotes: 0
Views: 802
Reputation: 49049
To get the rows in the order that you need, you could use this:
select
computer,
drive,
coalesce(pid, id)
from
your_table
order by
coalesce(pid, id), computer is null, drive is not null
this will order rows by pid
or (if pid
is null) by id
, and put rows where computer is not null at the top (since computer is null
is evaluated as 0 when it's false, and 1 when it's true), and then rows with drive null at the top.
(of course, if computer and drive can't be null at the same time, you could just order by just computer is null
)
You might also consider this order by clause:
order by coalesce(pid, id), computer is null, computer, drive is not null, drive
Upvotes: 0
Reputation: 71384
I would question your table structure. I would think computers and drives should be in two separate but related tables, since they are two different things, potentially with their own properties.
computer table:
computer_id | manufacturer
---------------------------
1 | dell
2 | apple
3 | hp
computer_id would be auto-incrementing primary key
drive table:
drive_id | computer_id | name
-----------------------------------
1 | 1 | WD300FV
2 | 1 | WD440GB
3 | 2 | WD55
4 | 2 | WD44X
5 | 3 | XYZ
drive_id would be auto-incrementing primary key
computer_id would have index (and possibly foreign key constraint if you are using InnoDB and wanted to enforce a relationship to computer table)
Then you would query like this:
SELECT c.computer_id, c.manufacturer, d.drive_id, d.name
FROM computer AS c
INNER JOIN drive AS d ON c.computer_id = d.computer_id
ORDER BY c.computer_id ASC, d.drive_id ASC
If, for whatever reason, you didn't want to go with a normalized structure like I have proposed and instead use a de-normalized structure like similar to what you already have, you should at least consider doing your de-normalization in a more sane way. There is no need for your pid
logic at all if you just structured your table like this:
computer | drive
------------------
dell | WD300FV
dell | WD4440GB
apple | WD55
apple | WD44X
hp | XYZ
You are just adding a level of complexity that doesn't need to be there. You could easily sort your result by "computer":
SELECT computer, drive FROM table
ORDER BY computer ASC, drive ASC
With no schema changes at all you could query like this:
SELECT computer, drive, CASE WHEN pid = '' THEN id ELSE pid END as `sort_id`
FROM table
ORDER BY `sort_id` ASC, drive ASC
Upvotes: 1