I am using Sql Server 2008 r2.
I have the following tables: Family, FamilyChild, Scale, Allowance.
I need to retrieve the number of children per family in order to select the appropriate value in the Scale table and then insert this value with many other fields (from these or other tables) in the Allowance table.
I need to do this for each family row in the family table.
How can I do this as simple as possible ?
Thanks.
Assuming that every row on FamilyChild represents one child:
SELECT F.FamilyID,
COUNT(*) NumberOfChildren
FROM Family F
LEFT JOIN FamilyChild FC
ON F.FamilyID = FC.FamilyID
GROUP BY F.FamilyID
Without the fields of the tables (and thoses needed to join the tables, you will not have a very appropriate answer. All I can say is: use a count() with the group by operator:
select f.family_name, count(c.children_id)
from family f inner join familyChild c on f.family_id = c.family_id
Then you can join this with the scale table or use it in and EXISTS subquery to filter the scale table and do your insert.
while using aggregate functions like count,max you should use group by clause with select statement and the columns which are not participated in aggregate function should be group by clause....for example
select f.family_name, count(c.children_id)
from family f inner join familyChild c on f.family_id = c.family_id
group by f.family_name
Related
How can I unite two select statement in one table result?
For instance in the first table I want to get everything however on my 2nd table I only want the corel name that is equal to the corel_id and id of my 2nd table?
SELECT *
FROM garage
UNION
SELECT c.name
FROM corel as c
WHERE EXISTS (SELECT 1 FROM garage as g WHERE c.id = g.corel_id
I tried to execute this but this did not work. Is this right? or is there a better way to do this?
Sorry newbie here.
UPDATE EXPECTED RESULT :
https://anotepad.com/notes/b6662w
Give this a try:
SELECT g.*, c.name
FROM garage g
LEFT JOIN corel c
ON c.id = g.corel_id
Matching two tables in a database is called a join. An inner join, the default, returns only the rows that match from both tables.
A left join returns all the rows from the first table whether or not they match the second, and any data from the second table that matches. The right join does the inverse, returning only non-matching data from the second table. There is also the full join that returns all data regardless of match.
A join statement is what you need. A join puts columns from multiple tables into rows together based in the matching conditions in the where clause.
A union requires 2 or more queries to have the same columns. The union puts the sets of rows together into a longer set or rows.
I have a list of persons in a table. I then have another table where I correlate each person to one or more groups. Some persons have only one entry in the groups table but some have multiple.
I am now trying to SELECT list of persons that are in two specific groups. Person must be in BOTH groups in order to qualify.
My table with the basic information on the persons is base and the table with the group correlation is groups_registration. In fact I also have a third table where the groups names and further information are stored but it is not required for this query.
The groups I am trying to gather in this example are 4 and 11.
What I tried initially was:
SELECT base.*, groups_registration.person_id, groups_registration.group_id
FROM base
INNER JOIN groups_registration
ON base.id = groups_registration.person_id
WHERE (groups_registration.group_id = '4' AND groups_registration.group_id = '11')
ORDER BY base.name
This did not get my any response, I assume because no single row contains both group_id = 4 and group_id 11.
I have been searching through stackoverflow with no joy. Do you guys have any ideas?
Obviously, no row has both values. Use group by:
SELECT gr.person_id, groups_registration.group_id
FROM groups_registration gr
WHERE gr.group_id IN (4, 11)
GROUP BY gr.person_id
HAVING COUNT(DISTINCT gr.group_id) = 2;
I'll let you figure out how to join in the additional information from base.
Notes:
Use table aliases to make it easier to write and read queries.
Presumably, the ids are numbers. Compare numbers to numbers. Only use single quotes for date and string constants.
IN is better than long chains of OR/=.
You can use joins as shown below:
SELECT A.*, B.person_id, B.group_id
FROM base A
INNER JOIN
(SELECT gr.person_id, groups_registration.group_id
FROM groups_registration gr
WHERE gr.group_id IN (4, 11)
GROUP BY gr.person_id
HAVING COUNT(DISTINCT gr.group_id) = 2) B
ON A.id = B.person_id;
This will give you all the desired fields.
I'm joining two tables based on id_order and it's one to many relation. My query looks like this:
SELECT
ps_order_detail.product_name,
ps_order_history.id_order_state
FROM ps_order_detail JOIN
ps_order_history using (id_order)
The problem is that it returns all of the id_order_state values, and I want only the highest one. I tried doing max(ps_order_history.id_order_state) but it returns only one record with the highest value, and I want to have the highest value for each id_order. How can I do it?
You need to use aggregate function max with a group by clause. I am not sure which flavor of SQL server you are using. For MS SQL Server following query will do what you want.
SELECT product_name, MAX(id_order_state)
FROM ps_order_detail
GROUP BY product_name
One approach is to generate a subset of the max ID_ORDER_STATE per order and add it to the joins.
SELECT ps_order_detail.product_name
, ps_order_history.id_order_state
FROM ps_order_detail
INNER JOIN ps_order_history using (id_order)
INNER JOIN (SELECT max(ID_ORDER_STATE) MOS, ID_ORDER
FROM ps_order_history
GROUP BY ID_ORDER) Z
on Z.MOS = ps_order_history.id_order_state
and Z.ID_ORDER = ps_order_history.id_order
This approach allows you to return the other data from history related to the max record; but it's overkill if all you need is the max order state for each product name
Other approaches involve using cross apply or analytical functions but mySQL doesn't support those approaches.
I suppose you could use an exists and correlate subquery as well... but I find the above approach clean to read.
I'm trying to do a select from 2 tables. However in table B I need to get a value from table A.
I'm simplifying this for the sake of ease, but the end result is a very complex query, and this is the only part thats causing problems.
In this example we're using 2 tables - one for members, one for the membership they are linked to.
Here's the code:
SELECT member.id member.name, member.email .membership.type, membership.status FROM
(
(SELECT * FROM tbl_members) AS member,
(SELECT * FROM tbl_memberships WHERE tbl_memberships.memberid = member.id) AS membership
)
The problem is that in the second select query, you cant access member.id, so how would you go about accessing information from the first query, in the second query, if this is even possible. If it isn't possible, what are the other options, bearing in mind a join cant return multiple columns.
But a join can return multiple columns:
SELECT *
FROM tbl_members m
JOIN tbl_memberships ms
ON ms.memberid = m.id
Why don't you use left join, if join is not returning all columns from tbl_members
SELECT *
FROM tbl_members
Left JOIN tbl_memberships
ON tbl_memberships.memberid = tbl_members.id
This is the query that I am using to match up a members name to an id.
SELECT eve_member_list.`characterID` ,eve_member_list.`name`
FROM `eve_mining_op_members`
INNER JOIN eve_member_list ON eve_mining_op_members.characterID = eve_member_list.characterID
WHERE op_id = '20110821105414-741653460';
My issue is that I have two different member lists, one lists are members that belong to our group and the second list is a list of members that do not belong to our group.
How do i write this query so that if a member is not found in the eve_member_list table it will look in the eve_nonmember_member_list table to match the eve_mining_op_members.characterID to the charName
I apologize in advance if the question is hard to read as I am not quite sure how to properly ask what it is that I am looking for.
Change your INNER JOIN to a LEFT JOIN and join with both the tables. Use IFNULL to select the name if it appears in the first table, but if it is NULL (because no match was found) then it will use the value found from the second table.
SELECT
characterID,
IFNULL(eve_member_list.name, eve_nonmember_member_list.charName) AS name
FROM eve_mining_op_members
LEFT JOIN eve_member_list USING (characterID)
LEFT JOIN eve_nonmember_member_list USING (characterID)
WHERE op_id = '20110821105414-741653460';
If you have control of the database design you should also consider if it is possible to redesign your database so that both members and non-members are stored in the same table. You could for example use a boolean to specify whether or not they are members. Or you could create a person table and have information that is only relevant to members stored in a separate memberinfo table with an nullable foreign key from the person table to the memberinfo table. This will make queries relating to both members and non-members easier to write and perform better.
You could try a left join on both tables, and then selecting the non-null results from the resulting query -
select * from
(select * from
eve_mining_op_members as x
left join eve_member_list as y1 on x.characterID = y1.characterID
left join eve_member_list2 as y2 on x.characterID = y2.characterID) as t
where t.name is not null
Or, you could try the same thing with a union and using inner join (assuming joined tables are the same):
select * from
(select * from eve_mining_op_members as x
inner join eve_member_list as y1 on x.characterID = y1.characterID
UNION
select * from eve_mining_op_members as x
inner join eve_member_list2 as y2 on x.characterID = y2.characterID) as t
You can throw in your op_id condition where you see fit (sorry, I didn't really understand where it came from). Good luck!
You have several options but by
using a UNION between the eve_member_list and eve_nonmember_member_list table
and JOIN the results of this UNION with your original eve_mining_op_members table
you will get your required results.
SQL Statement
SELECT lst.`characterID`
, lst.`name`
FROM `eve_mining_op_members` AS m
INNER JOIN (
SELECT characterID
, name
FROM eve_member_list
UNION ALL
SELECT characterID
, name
FROM eve_nonmember_member_list
) AS lst ON lst.characterID = m.characterID
WHERE op_id = '20110821105414-741653460';