So all I want to do is have a view that shows how many kid between and including the age of 5 - 18 are in each family. I AM USING SQL SERVER.
The view I Have written to get the Family Members Ages is
CREATE VIEW VActiveMembers
AS
SELECT
TM.intMemberID AS intMemberID,
TM.strFirstName AS strFirstName,
TM.strLastName AS strLastName,
TM.strEmailAddress AS strEmailAddress,
TM.dtmDateOfBirth AS dtmDateOfBirth,
FLOOR(DATEDIFF(DAY, dtmDateOfBirth, GETDATE()) / 365.25) AS intMemberAge
FROM
TMembers AS TM
WHERE
TM.intStatusFlagID = 1
intStatusFlag = 1 is just a flag that means the member is active.
Now I have tried for about 3ish hours to figure this out but I cannot figure it out. Here is the one where instead of trying to get the solution in one fowl swoop I tried to step wise it, but then I still didn't get the result I wanted.
As you can see I didn't use the view where I calculated the AGE from because the "Multi-part Identifier could not be bound" I have seen that error but I couldn't get it to go away in this case. Ideally I would like the count to be performed on the VIEW instead of recalculating the ages all over again
CREATE VIEW VActiveFamilyMembersK12Count
AS
SELECT
TF.intParishFamilyID,
COUNT(DATEDIFF(DAY, dtmDateOfBirth, GETDATE()) / 365) AS intMemberAgeCount
FROM
TFamilies AS TF
INNER JOIN
TFamilyMembers AS TFM
INNER JOIN
VActiveMembers AS vAM ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF.intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID
I wanted to just get a count using the age calculation just to see If I could get a correct count of members in a family, then I could start building upon that to get a count of members of a certain age. The result I get back is 2 but there are guaranteed 3 members to each family.
The result I am looking For is this
Family_ID | K12Count
-----------------------------
1001 | 2
1002 | 0
1003 | 1
1004 | 0
Here is a list of resources I looked up trying to figure this out, maybe one of them is in fact the answer and I just don't see it, but I am at a loss at the moment.
SQL Select Count from below a certain age
How to get count of people based on age groups using SQL query in Oracle database?
Count number of user in a certain age's range base on date of birth
Conditional Count on a field
http://timmurphy.org/2010/10/10/conditional-count-in-sql/
*** EDIT ***
CREATE VIEW VActiveFamilyMembersK12Count
AS
SELECT
TF.intParishFamilyID,
SUM(CASE WHEN intMemberAge >= 5 AND intMemberAge <= 18 THEN 1 ELSE 0 END) AS intK12Count
FROM
TFamilies AS TF
INNER JOIN TFamilyMembers AS TFM
INNER JOIN VActiveMembers AS vAM
ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF. intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID
GO
THIS IS THE SOLUTION ABOVE.
Conditional count is the way to go.
Something like:
SELECT intParishFamilyID,
COUNT(CASE WHEN intMemberAge >=5 and intMemberAge <=18 THEN 1 ELSE 0 END)
FROM
TFamilies AS TF
INNER JOIN TFamilyMembers AS TFM
INNER JOIN VActiveMembers AS vAM
ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF. intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID
Related
I don't know how to title this because I'm not sure about how to solve it or if it can be solved.
I have a list of products made of different components and I'd like to know how many I can produce taking in count these components can be produced through some other components.
Let's say this is my table of product structures:
CODE COMPONENT NEEDED
PROD1 BLISTER 1
PROD1 BOX 1
PROD1 TOY 1
TOY RIGHT ARM 1
TOY LEFT ARM 1
TOY EYE 2
I have this stock:
CODE STOCK
PROD1 100
BLISTER 100
BOX 50
TOY 15
RIGHT ARM 20
LEFT ARM 20
EYE 40
With this subselect I know how many I can produce of each code:
(SELECT min(isnull(STK.STOCK/STR.NEEDED,0))
from STRUCTURE STR
left join STOCKWAREHOUSE STK
on STR.COMPONENT = STK.CODE
where STR.CODE = ART.CODE) as PRODUCIBLE
Now it shows something like this:
CODE PRODUCIBLE
PROD1 15
TOY 20
I don't know how could I take in count the components I can produce as well (like the Toy). I think I should join that table twice, connected to itself, but I don't know how I can sum each component with the producible amount of that component.
The desired result is this:
CODE PRODUCIBLE
PROD1 35
TOY 20
EDIT:
Thanks to the answer I managed to sum both producibles, but it's not working as expected. Let's say a box is made of these components:
COMPONENT STOCK PRODUCIBLE
TOY1 400 150
TOY2 150 100
TOY3 0 100
TOY4 100 10
Now, it calculates the minimum producible for the box at the first level: 0 (because of the TOY3), and the minimum producible at the second level: 10 (because of TOY4), and then it sums both: 0+10. I would need to sum the stock with the producible, returning 100.
Ask me if I need to clarify anything. Thank you very much!
EDIT2: Nvm, fixed by calling the component from main table and summing its stock.
This looks like a business logic so I think you should not be doing this in the DB level.
Below query should give you your desired output for the data that your provided.
First subquery is what your provided, second subquery looks into the same output but at a component level. Finally you are adding both producible on the select.
select a.code1 as Code , a.p1 + isnull(c.p,0) as PRODUCIBLE
from
(
SELECT STR.CODE code1, min(isnull(STK.STOCK/STR.NEEDED,0)) p1
from STRUCTURE STR
left join STOCK STK
on STR.COMPONENT = STK.CODE
GROUP BY STR.CODE
) as a
full outer join
(
select s.CODE code, code component, b.p
from STRUCTURE s
join
(SELECT STR.CODE code, min(isnull(STK.STOCK/STR.NEEDED,0)) p
from STRUCTURE STR
left join STOCK STK
on STR.COMPONENT = STK.CODE
GROUP BY STR.CODE
) as b on b.code = s.COMPONENT
) as c on a.code1 = c.code
I have a query that I have had make do over the last few years which heavily leans on the users entering in data in a somewhat correct order (i know, first mistake).
The idea is that the users enter a item with the category of CRT in the first 7 lines...and only one. Some times there may be others with this category, but i only want the first one. Now, users sometimes enter the item in after the first 7 rows...leading to another problem. Here is my original query:
Select distinct
d.Job_Number as Rig,
case d.Customer_Name
when 'case' then 'diff case'
else '******'
end as Parent_Customer,
d.Customer_Name,
case d.Reference_Location2
when 'case' then 'diff case'
else '******'
end as Size,
case d.Office_code
when 'case' then 'diff case'
else '****'
end as Office,
d.Rental_Ticket,
case d.job_type
when 'case' then 'diff case'
else '0'
end as Billable,
d.Reference_Location5 as TT
from HP_View_DEL_Ticket_Header_Master as d
left join CSView_INVC_Header_Master as i --left join to report jobs that have not been invoiced
on d.Rental_Ticket = i.Rental_Ticket_or_Tag_Number
join CSView_DEL_Ticket_Lines_Master as l
on d.Rental_Ticket = l.Rental_Ticket
where (d.Ticket_Month between 7 and 7 and d.Ticket_Year = 2017)-- or (d.Ticket_Month between 12 and 12 and d.Ticket_Year = 2016))
and d.Rental_Ticket not in (select dticket from deltick_void)
and d.Ticket_Type = 'D'
and d.Posted_Flag = -1
and l.Row_Counter between 1 and 7 --Currently how I get the correct record, problem is its sometimes not entered in the first 7 rows.
and l.Category_Code = 'CRT'
order by Parent_Customer
I am needing one Ticket number, to one CRT item (the CRT first item). I've tried doing something in the where clause to find the top CRT items but didn't work the way i figured it would.
Any help would be great.
Thanks
BD
EDIT:
Expected OUTPUT
Rig Parent_Customer Customer_Name Size Office Rental_Ticket Billable TT
RIG 642 A A 5 to 5.5 City 12627 0 YES
RIG 525 B B 5 1/2 City 2 12628 0 YES
RIG 603 C C 9 5/8 City 3 12634 0 NO
Incorrect OUTPUT:
Rig Parent_Customer Customer_Name Size Office Rental_Ticket Billable TT
RIG 642 A A 5 to 5.5 City 12627 0 YES
RIG 642 A A 5 to 5.5 City 12627 0 YES
Because the query finds more than one 'CRT' on the Rental Ticket, it returns two records that are the same for the columns I have selected. I am wanting to use ONLY the first one it finds.
I'm working on a report that shows transactions grouped by type.
Type Total income
------- --------------
A 575
B 244
C 128
D 45
E 5
F 3
Total 1000
I only want to provide details for transaction types that represent more than 10% of the total income (i.e. A-C). I'm able to do this by applying a filter to the group:
Type Total income
------- --------------
A 575
B 244
C 128
Total 1000
What I want to display is a single row just above the total row that has a total for all the types that have been filtered out (i.e. the sum of D-F):
Type Total income
------- --------------
A 575
B 244
C 128
Other 53
Total 1000
Is this even possible? I've tried using running totals and conditionally hidden rows within the group. I've tried Iif inside Sum. Nothing quite seems to do what I need and I'm butting up against scope issues (e.g. "the value expression has a nested aggregate that specifies a dataset scope").
If anyone can give me any pointers, I'd be really grateful.
EDIT: Should have specified, but at present the dataset actually returns individual transactions:
ID Type Amount
---- ------ --------
1 A 4
2 A 2
3 B 6
4 A 5
5 B 5
The grouping is done using a row group in the tablix.
One solution is to solve that in the SQL source of your dataset instead of inside SSRS:
SELECT
CASE
WHEN CAST([Total income] AS FLOAT) / SUM([Total income]) OVER (PARTITION BY 1) >= 0.10 THEN [Type]
ELSE 'Other'
END AS [Type]
, [Total income]
FROM Source_Table
See also SQL Fiddle
Try to solve this in SQL, see SQL Fiddle.
SELECT I.*
,(
CASE
WHEN I.TotalIncome >= (SELECT Sum(I2.TotalIncome) / 10 FROM Income I2) THEN 10
ELSE 1
END
) AS TotalIncomePercent
FROM Income I
After this, create two sum groups.
SUM(TotalIncome * TotalIncomePercent) / 10
SUM(TotalIncome * TotalIncomePercent)
Second approach may be to use calculated column in SSRS. Try to create a calculated column with above case expression. If it allows you to create it, you may use it in the same way as SQL approach.
1) To show income greater than 10% use row visibility condition like
=iif(reportitems!total_income.value/10<= I.totalincome,true,false)
here reportitems!total_income.value is total of all income textbox value which will be total value of detail group.
and I.totalincome is current field value.
2)add one more row to outside of detail group to achieve other income and use expression as
= reportitems!total_income.value-sum(iif(reportitems!total_income.value/10<= I.totalincome,I.totalincome,nothing))
Just can't seem to figure this out, although it seems rather simple.
Table: Attd (...short for Attendance)
Visit Person Status Date
1 1 Member 2011-01-31
2 1 Member 2011-02-05
3 2 Member 2011-02-05
4 3 Not 2011-01-07
5 1 Not 2011-01-25
6 1 Not 2011-01-20
7 1 Not 2011-02-03
The data belongs to visits to a location by individuals, which includes if they had a membership (Status column).
How would you select visits that took place one week before someone became a member (Same person: Status=Not --> Status=Member)? [Output row 5 above.]
For example,
Person 2 became a member without visiting before, because they had no Status=Not before they joined.
Person 3 visited as a non-member and never came back.
And, person 1 visited as a non-member (Status=Not on 2011-01-25) and became a member within one week (Status=Member on 2011-01-31).
Preliminary work:
a. Pretty sure the answer contains a self join
b. The dateAdd function help satisfy the one week before condition
Try this simple query:
SELECT t1.Person
FROM
(SELECT *
FROM attd
WHERE status = 'member')T1
INNER JOIN
(SELECT *
FROM attd
WHERE status = 'not')T2 ON T1.Person = T2.Person
WHERE datediff(dd,T2.Date,T1.Date)<=7
You can find a working example on SQLFiddle.
Hope this helps you and feel free to contact me if you have any more questions.
First use aggregation to calculate the member date for each person. This is presumably the minimum date where there is a status of 'Member'. Then do a join back to the table to get earlier visits:
select *
from (select a.person, min(date) as MemberDate
from Attendance a
where status = 'Member'
group by a.person
) m join
Attendance aprev
on m.person = aprev.person and
datediff(d, aprev.date, MemberDate) <= 7 and
aprev.status = 'Not';
Strictly speaking the last condition 'aprev.status = 'Not' is unnecessary, because those are the only statuses before the member date. However, I think it clarifies the intent of the query.
I have a stored procedure (I cannot edit) that I am calling via linq.
The stored procedure returns values (more complex but important data below):
Customer Stock Item Date Price Priority Qty
--------------------------------------------------------
CUST1 TAP 01-04-2012 £30 30 1 - 30
CUST1 TAP 05-04-2012 £33 30 1 - 30
CUST1 TAP 01-04-2012 £29 20 31 - 99
CUST1 TAP 01-04-2012 £28 10 1 - 30
I am trying to limit this list to rows which have unique Dates and unique quantities in LINQ.
I want to remove items with the HIGHER priority leaving rows with unique dates and qty's.
I have tried several group by's using Max and order by's but have not been able to get a result.
Is there any way to do this via linq?
EDIT:
Managed to convert brad-rem's answer into VB.net.
Syntax below if anyone needs it:
returnlist = (From p In returnlist
Order By p.Qty Ascending, p.Priority
Group By AllGrp = p.Date, p.Qty Into g = Group
Select g.First).ToList
How about the following. It groups by Date and Qty and orders it so that the lower priorities come first. Then, it just selects the first item from each group, which are all the lower priority items:
var result = from d in dbData
orderby d.Priority
group d by new
{
d.Date,
d.Qty
} into group1
select group1.First();