In Parse you can select or include a key from a pointer. Select key Parent.child.id
Is it possible to do the same in SQL if you have child indexed to parent?
SELECT Parent.child.id
In SQL you do this:
Select * from parent, child where parent.id = child.id;
Related
I have a categories table with the following columns:
id
name
parent_id (nullable)
And a books table which has a category_id column inside of it.
I want a function that takes a list of category ids (category_ids) and returns a query that gets books which belong to one of the given categories or their children (recursive).
I've already written a query that returns all of a given category's children. I could use that to fetch all of the subcategories of category_ids categories and use the new list. But it would send several queries to the database and I want to do it in one query. Here's the query:
with recursive cat_tree as (
select id,
name,
parent_id
from categories
where id = $1
union all
select child.id,
child.name,
child.parent_id
from categories as child
join cat_tree as parent on parent.id = child.parent_id
)
select *
from cat_tree;
EDITED
#raw_sql """
select id,
name,
parent_id
from categories
where id in (?)
union all
select child.id,
child.name,
child.parent_id
from categories as child
join cat_tree as parent on parent.id = child.parent_id
"""
def category_search_query(query, []), do: query
def category_search_query(query, category_ids) do
query
|> recursive_ctes(true)
|> with_cte("cat_tree", as: fragment(#raw_sql, ^category_ids))
|> join(:inner, [b], c in "cat_tree", on: c.id == b.category_id)
end
But when I pass [12, 13] (for example) to the function, it gives me the following error:
(DBConnection.EncodeError) Postgrex expected an integer in -9223372036854775808..9223372036854775807, got '\f\r'. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.
But when I pass just an integer (and not a list), it works correctly.
I would make a procedure to get list of categories as parameter (can be an array) and change your query to this :
create function funcName (categoryIds int[])
returns table ( bookid int ,categoryid int , ...<deffine book columns>)
as
$$
with recursive cat_tree as (
select
id,name,parent_id
from
categories
where id in (select unnest(categoryIds))
union all
select
child.id,child.name,child.parent_id
from
categories as child
join cat_tree as parent on parent.id = child.parent_id
)
select
b.*
from
cat_tree c
join books on c.id = b.categoryid
$$ Language sql;
I have to see I am new to sql.
I have a table which looks like this:
child parent
-------------------
Nancy Bob
Oli Bob
Alice Oli
Mira Alice
Now I need sql statement which gives me parent -which is already known- and its children and children of its children... etc, given is parent name.
Example I need Family of Bob. The sql should return (Bob, Nancy, Oli, Alice, Mira)
I tried this: select child from myTable where parent='Bob' This gives me Nancy and Oli.
Any Idea?
You can use Oracle's hierarchial queries to get this along with the level of tree:
Demo
SELECT CHILD, LEVEL FROM TABLE1
START WITH PARENT = 'Bob'
connect by prior child = parent;
That’s a typical hierarchical query. One standard method uses a recursive with clause:
with cte (child, parent) as (
select child, parent from mytable where parent = 'Bob'
union all
select t.child, t.parent
from mytable t
inner join cte c on c.child = t.parent
)
select child from cte
I should get root element with all descendants from that structure:
rootA
rootB
child1
rootC
child2
chold3
rootD
child4
RESULT:
Root| Child
rootA child1
rootA child2
rootA child3
rootD child4
I understand, that firstly I should get root elements without parents:
SELECT DISTINCT
rootId,
childId
FROM
root
WHERE rootId IS NULL
But I dont know the next step.
Do you have some variants?
Thanks!
This is done with a Common Table Expression (CTE):
;WITH cte_hierarchy AS (
-- get all roots
SELECT DISTINCT
rootId, childId
FROM
root
WHERE rootId IS NULL
UNION ALL
-- this is the recursive part
-- get all children for all roots, including children of children, etc.
SELECT
child.rootId, child.childId
FROM root child
JOIN cte_hierarchy parent ON parent.childid=child.rootid
)
SELECT * FROM cte_hierarchy;
I have 2 tables with a parent-child relation. I'd like to return a row with NULL child values for parents that have children, in addition to the child records.
For example, for tables parent and child:
SELECT parent.parentid, childid
FROM parent
LEFT JOIN child
ON parent.parentid=child.parentid
For a parent parentA with children childA1, childA2, I'd like a result:
parentA, NULL
parentA, childA1
parentA, childA2
A normal LEFT JOIN will not return the first row. A UNION query works, but I'm wondering if there is a simpler/better query, using standard SQL for Oracle and SQL Server. My UNION query is:
SELECT parent.parentid, childid
FROM parent
INNER JOIN child ON parent.parentid=child.parentid
UNION
SELECT parent.parentid, NULL
FROM parent
I think your query is better written as:
SELECT p.parentid, childid
FROM parent p INNER JOIN
child c
ON p.parentid = c.parentid
UNION ALL
SELECT p.parentid, NULL
FROM parent p;
That is UNION ALL is better than UNION, because UNION has additional overhead for removing duplicate values. If you can have duplicates in parent, just use SELECT DISTINCT in the second query.
Also, you might want to add an ORDER BY to get results in order the question seems to specify:
ORDER BY parentid, (CASE WHEN child is NULL then 0 else 1 end), chile
An alternative way of doing it would be
SELECT parent.parentid,
childid
FROM parent
LEFT JOIN child
ON parent.parentid = child.parentid
GROUP BY GROUPING SETS( ( parent.parentid ), ( parent.parentid, childid ) )
HAVING (childid IS NOT NULL) OR GROUPING(childid) =1
ORDER BY parentid ASC,
GROUPING(childid) DESC
If you only want the row for parents with children you should use an inner join
SQL Fiddle - Oracle
SQL Fiddle - SQL Server
I've a table:
Id | Name | ParentID
I want to select records whose parentid not equal to zero, with parent record(parent record have parentid = 0, but some parent record don't have child record I want to skip them )
Try this:
SELECT child.Id,
child.Name,
child.ParentId,
parent.Name as ParentName
FROM your_table child
JOIN your_table parent ON child.ParentId = parent.id;
Check this one:
select * from child c,parent p where c.ID=P.ParentID and c.ParentID !=0