Query Handling Sql Server - sql

Please help me regarding query. I am pretty weak in DBMS.
I have a table TBLParent which has some rows as follows
pkParentId FKProductId Name
1 5 P1
2 5 P2
3 3 P3
and I have another table TBLChild that consist of its children
pkId fkParentId ChildName
1 1 C1
2 1 c2
3 2 c1
Now, question is I want Parent records and count of its children based on productId.
For example: I want to
select
TBLParent.pkParentId, TBLParent.FKProductId,
TBLParent.Name,
count of its children
where
TBLParent.FKProductId = 5
I tried like this
Select
count(TBLChild.pkId) AS total,
TBLChild.fkParentId
from
TBLChild
group by
TBLChild.fkParentId
but how can I attach records of parent table with this count?
This will give me count but How I will attach parent record with this count. I mean to say output would be
pkParentId Name Count
1 P1 2
2 P2 1
Please help please help please help?

SELECT P.pkParentId
,P.Name
,COUNT(*)
FROM tblParent P
INNER JOIN tblChild C ON P.pkParentId = C.fkParentId
WHERE P.pkParentId = #yourValueHere
GROUP BY P.pkParentId, P.Name

Related

Get data from relational tables

I have following tables in my db.
Calls:
ID Name
1 Call1
2 Call2
3 Call3
Notes:
ID Name
1 Note 1
2 Note 2
Person:
ID Name
1 Andrew
PersonCalls:
ID CallID PersonID
1 1 1
2 2 1
PersonNotes:
ID NoteID PersonID
1 1 1
1 2 1
Now I need to get data from these tables according to person id. I am able to get data from 2 tables, for example Notes and PersonNotes, but I am not able to get combined data from these tables. This should be the result.
Result:
PersonID Note Call
1 Note1 Call1
1 Note2 Call2
Please suggest
Thanks
Use Join (ie: Inner Join):
select distinct p.ID as PersonID, n.Name as Note, c.Name as Call from Person p
inner join PersonCalls pc on p.ID = pc.PersonID
inner join PersonNotes pn on p.ID = pn.PersonID
inner join Calls c on pc.CallID = c.ID
inner join Notes n on pn.NoteID = n.ID
Without getting too detailed you can use a left join on dbo.calls.ID, dbo.notes.id, dbo.person.id, etc if you are using MS SQL server. Otherwise are you sure you can't just write a report?

SQL joining to the same column id

I have a simple SQL query I just get to work out right. I've put together a test database like this;
TABLE MAIN
id name groupone grouptwo
1 Fred 1 3
2 bob 2 1
TABLE DETAIL
id group groupname
1 1 onegrp
2 2 twogrp
4 3 threegrp
My Select query is;
SELECT name, groupone, grouptwo, groupname
FROM main
INNER JOIN detail
ON main.groupone = detail.group
WHERE main.id = 1
The result I get is;
id name groupone grouptwo groupname
1 fred 1 3 onegrp
How do I change this to instead of giving the result as 1 and 3.
I get ... fred onegrp, threegrp
I've tried a dozen things but can't get it to work, I sort of want a give me the groupname again option but not sure what the syntax is for that! :(
Thanks in advance for your time and help
I think this is what you are after. You need to join the detail table twice, on the two different keys.
SELECT
m.Name
,a.groupname as 'GroupOne'
,b.groupname as 'GroupTwo'
FROM
main m
INNER JOIN
detail a
on m.groupone = a.group
INNER JOIN
detail b
on m.grouptwo = b.group
WHERE
m.id = 1

Linking and counting records with one or multiple criteria

I am attempting to link together some records to identify sibling groups. The way we can do this is to identify clients who share the same parents.
A sample of the SQL follows:
SELECT
A.ClientID,
B.ParentID
FROM A
LEFT JOIN B ON B.ClientID to A.ClientID
AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
Which would return data in the following format:
Client ID Parent ID
1 A
1 B
2 C
2 D
3 C
3 E
4 C
4 D
How I would like it to appear follows:
Client ID No. of Siblings
1 0
2 2
3 2
4 2
Hopefully the table shows that child 1 has 0 siblings (shares no parents with 2,3,4), child 2 has 2 siblings (3 and 4), child 3 has 2 siblings (2 and 4) and child 4 has 2 siblings (2,3). It seems like it should be simple enough to achieve this but I'm really struggling at the minute to think how! I think it's made slightly more confusing because a child may share only one parent with another child to be considered as a sibling.
Hopefully this is clear, thanks.
Edit: Just to make it clear, the relationship is identified by a child sharing a parent ID with another child (the ids are unique, but I provided generic ones for this example). So as Child 2, 3 and 4 all have a parent with an id of C they are considered siblings.
You may try this query, it displays to me the desired output.
with c_data as (
select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by parentid) as c_parents
FROM A
LEFT JOIN B ON (B.ClientID = A.ClientID)
AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
)
select clientid as "Client ID", max(c_parents) -1 as "No of Siblings"
from c_data
group by clientid;
Example:
SQL> with c_data as (
2 select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by parentid) as c_parents
3 FROM A
4 LEFT JOIN B ON (B.ClientID = A.ClientID)
5 AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
6 )
7 select clientid as "Client ID", max(c_parents) -1 as "No of Siblings"
8 from c_data
9 group by clientid;
Client ID No of Siblings
---------- --------------
1 0
2 2
4 2
3 2
Transcurrido: 00:00:00.03
SQL>
With the analytic function we count all client id's partitioned by the parentid related of the current tupple to count all clients that have in common the same parent.
After in the projection, we get the max number of parent in common for each client and substracts 1, the client itself.
Hope this helps!
Regards!
This is rather complicated. If you can assume exactly two parents for each child, then you can do something like:
select c.*, count(*) over (partition by min_parent, max_parent) - 1 as NumSiblings
from (SELECT A.ClientID, min(B.ParentID) as min_parent, max(b.parentid) as max_parent
FROM A LEFT JOIN
B
ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
group by a.clientid
) c
What this does is calculate the two parents for each client. It then uses the windows function to count the number of clients that have exactly the same parents. The "-1" is because all children are counted, and we don't want to count the current child.
If you can have more than two parents, then the query is more complicated.
If you want only one parent being shared (rather than two), then you can handle using a self join:
with cp as (SELECT A.ClientID, B.ParentID
FROM A LEFT JOIN
B
ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
)
select cp.client_id, count(distinct cp1.client_id) as NumSiblings
from cp left outer join
cp cp1
on cp.parent_id = cp1.parent_id and cp.client_id <> cp1.client_id
group by cp.client_id
Well, I don't understand how the table and relation are made, but you could do something like that :
SELECT ClientID, sum(NumberOfSibling) as NumberOfSibling
from(
SELECT A.ClientID, (select count(ClientID)
from A2
LEFT JOIN B2 ON B2.ClientID to A2.ClientID
AND B2.REL_END is NULL AND B2.REL_CODE = 'PAR'
where B2.ParentID = B.ParentID) as NumberOfSibling
FROM A
LEFT JOIN B ON B.ClientID to A.ClientID
AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
) GROUP BY ClientID
Explanation : I took your request and modify the second result to return the sum of siblings wich possess the same Parent (that's the select count(*) ..., that's also the part I'm not sure about the conditions). And put this in another to group by ClientID to have the sum of the 2 parents.

Joining 3 Tables Using Newest Rows

I have 3 tables in my database: children, families, statuslog
Every time a child is checked in or out of the database, it is updated in the statuslog. I've done this a long time ago, but I can't seem to figure out how to do it anymore. I want to create a new view that joins all 3 tables, but I only want the newest entry from statuslog (by using the highest id).
For example, statuslog looks like this:
childID researcher status id
1 Dr. A out 1
1 Dr. A in 2
1 Dr. B out 3
1 Dr. B in 4
2 Dr. C out 5
2 Dr. C in 6
3 Dr. B out 7
3 Dr. B in 8
This is what I want to do:
SELECT *
FROM children, families, statuslog
WHERE children.familyID = families.familyID AND children.childID = statuslog.childID
Obviously, this will return the children+families tuples coupled with every single log entry, but I can't remember how to only combine it with the newest log entry.
Any help would be appreciated!
Aggregate query with max(id) retrieves last ID given a childID. This is then joined to statuslog to retrieve other columns.
SELECT *
FROM children
INNER JOIN families
ON children.familyID = families.familyID
INNER JOIN
(
SELECT childID, researcher, status
FROM statuslog
INNER JOIN
(
SELECT childID, max(ID) ID
FROM statuslog
GROUP BY childID
) lastSL
ON statuslog.childID = lastSL.childid
AND statuslog.ID = lastSL.ID
) sl
ON children.childID = sl.childID
This seems to be the typical greatest-n-per-group in which the higher id is interpreted as the newest. This query should do the trick:
select * from (
select s1.* from statusLog s1
left join statusLog s2
on s1.childId = s2.childId and s1.id < s2.id
where s2.id is null
) final
join children c on c.childId = final.childId
join families f on f.familyId = c.familyId
Correct any syntactical errors.

SQL query: need help on subquery

Question is as follows:
There are 2 related tables (am giving some sample values for making it simplified):
Circuit
--------
id name
1 a
2 b
3 c
Circuit_Dependent
-----------------
id depend_id
1 2
1 3
the tables are related and second table tells the relation with the circuit id's.
Situation is query needed for:
1) list the circuit name which has the circuit_dependency
output expected:
name dependent_name
a b
a c
2) list the circuit name and count(no of dependancies)
output expected:
name count
a 2
appreciate help.
First query could be:
SELECT c1.`name`, c2.`name`
FROM Circuit_Dependent cd INNER JOIN Circuit c1
ON cd.id = c1.id
INNER JOIN Circuit c2
ON cd.depend_id = c2.id
Second query could be this one:
SELECT c.`name`, COUNT(DISTINCT cd.depend_id) AS count
FROM circuit c INNER JOIN Circuit_Dependent cd
ON c.id = cd.id
GROUP BY c.id