I have the following table in Google Cloud Spanner for categories.
CREATE TABLE categories (
categoryId STRING(36) NOT NULL,
name STRING(128) NOT NULL,
parent BOOL NOT NULL,
parentId STRING(36),
archived BOOL,
FOREIGN KEY (parentId) REFERENCES categories (categoryId)
) PRIMARY KEY(categoryId);
So the table might have entries as shown below.
| categoryId | name | parent | parentId | archived |
|---|---|---|---|---|
| 1 | Clothing | true | false | |
| 2 | Homeware | true | false | |
| 3 | Shirts | false | 1 | false |
| 4 | Pants | false | 1 | false |
| 5 | Technology | true | false | |
| 6 | Tablets | false | 5 | true |
I want to query this table such that it returns firstly all the parent categories that aren't archived (I can't really delete rows in my application, as documents will reference rows - so I implemented archiving), along with all the child categories (not archived) belonging to said parents.
I came as far as writing the following query:
SELECT categories.categoryId, categories.name, childCategories.name AS childName
FROM categories
LEFT JOIN categories AS childCategories
ON childCategories.parentId = categories.categoryId
WHERE categories.parent = true AND categories.archived = FALSE
However, this will return rows where child categories are archived. Below is the exact result returned.
| categoryId | name | childName |
|---|---|---|
| 1 | Clothing | Shirts |
| 1 | Clothing | Pants |
| 2 | Homeware | |
| 5 | Technology | Tablets |
The desired result would be:
| categoryId | name | childName |
|---|---|---|
| 1 | Clothing | Shirts |
| 1 | Clothing | Pants |
| 2 | Homeware | |
| 5 | Technology |
I have tried altering the query as:
SELECT categories.categoryId, categories.name, childCategories.name AS childName
FROM categories
LEFT JOIN categories AS childCategories
ON childCategories.parentId = categories.categoryId
WHERE categories.parent = true AND categories.archived = FALSE AND childCategories.archived = FALSE
This, however, won't return any parent categories if they don't have at least one child category. Below is the exact result returned.
| categoryId | name | childName |
|---|---|---|
| 1 | Clothing | Shirts |
| 1 | Clothing | Pants |
I can't figure out how to write the query to obtain the desired result. Any help/insight would be appreciated. Thanks in advance!
childCategories.archived = FALSEto the ON condition instead of Where.