SQL - Joining Two Tables and Sum of Column - sql

I have a situation where I have table A that have member info and table B that has a list of transactions for the members. I need to retrieve fields from Table A with a total of the transaction column for each member.
I have struggled with the proper SQL syntax and it keeps error on me. We are using MS Reporting Services to develop this if that helps.
Table A:
Member ID LName FName Phone
----------------------------------------------
1234 Doe John 555-555-5555
5678 Doe Jane 555-555-5550
Table B:
Member ID Transaction Date Transaction Total
----------------------------------------------------
1234 01-01-2020 120.00
1234 01-05-2020 25.00
5678 01-01-2020 50.00
5678 01-10-2020 50.00
5678 01-11-2020 25.00
1234 01-15-2020 25.00
Desired output:
Member ID: Last Name: First Name: Total:
----------------------------------------------------
1234 Doe John 170.00
5678 Doe Jane 125.00

You are looking for aggregation with group by & sum() :
select a.memberid, a.lname, a.fname, sum(b.transactiontotal) as total
from a inner join
b
on b.memberid = a.memberid
group by a.memberid, a.lname, a.fname;

Related

find out the records - first two date records of each member of every year- db2udb

Need Help -
Scenario - I have a table testdata with columns
memberid (varchar) ,codetype(varchar),effectivedate(datetime)
this table having 20k records - from year 2015 to 2021
I need to find out the records - first two date records of each member of every year [ only memberid is unique)
eg.
member id
codetype
effectivedate
123
ABC
1/2/2015
123
ABC
1/2/2015
123
ABC
8/15/2015
123
EFG
9/15/2015
123
EFG
2/15/2018
345
EFG
3/14/2018
345
EFG
3/17/2018
345
ABC
9/19/2020
456
EFG
12/20/2021
result should be like below
member id
codetype
effectivedate
123
ABC
1/2/2015
123
ABC
1/2/2015
123
ABC
2/15/2018
345
EFG
3/14/2018
345
EFG
3/17/2018
345
ABC
9/19/2020
456
EFG
12/20/2021
tried lot of ways but no luck so far
Try this
with u as
(select memberid, codetype, effectivedate,
row_number() over(partition by memberid, year(effectivedate) order by
memberid) as rownum
from testdata)
(select memberid, codetype, effectivedate from u
where rownum <= 2)
Basically you get the row numbers of every record partitioned by memberid and the year of the record, then keep only the records where rownum is 1 or 2.

How do I select a max date by person in a table

I am not too advanced with SSRS/SQL queries, and need to write a report that pulls out % allocations by person to then compare to a wage table to allocate the wages. These allocations change quarterly, but all allocations continue to be stored in the table. If a persons allocation did not change, they do NOT get a new entry in the table. Here is a sample table called Allocations.
First Name
Last Name
Date
Area
Percent
Smith
Bob
01/01/20
A
50.00
Smith
Bob
01/01/20
B
50.00
Doe
Jane
01/01/20
A
25.00
Doe
Jane
01/01/20
B
25.00
Doe
Jane
01/01/20
C
50.00
Doe
Jane
04/01/20
A
35.00
Doe
Jane
04/01/20
C
65.00
Wayne
Bruce
01/01/20
A
100.00
Wayne
Bruce
04/01/20
B
100.00
The results that I would want to have from this sample table when querying it are:
First Name
Last Name
Date
Area
Percent
Smith
Bob
01/01/20
A
50.00
Smith
Bob
01/01/20
B
50.00
Doe
Jane
04/01/20
A
35.00
Doe
Jane
04/01/20
C
65.00
Wayne
Bruce
04/01/20
B
100.00
However, I would also like to pull this by comparing it to a date that the user inputs, so that they could run this report at any point in time and get the correct "max" dates. So, for example, if there were also 7/1/20 dates in here, but the user input date was 6/30/20, I would NOT want to pull the 7/1/20 data. In other words, I would like to pull the rows with the maximum date by name w/o going over the user's input date.
Any idea on the best way to accomplish this?
Thanks in advance for any advice you can provide.
In SQL, ROW_NUMBER can be used to order records in groups by a particular field.
SELECT * FROM (
SELECT *, ROW_NUMBER()OVER(PARTITION BY Last_Name, First_Name ORDER BY DATE DESC) as ROW_NUM
FROM TABLE
) AS T
WHERE ROW_NUM = 1
Then you filter for ROW_NUM = 1.
However, I noticed that there are a couple with the same date and you want both. In this caseyou'd want to use RANK - which allows for ties so there may be multiple records with the same date that you want to capture.
SELECT * FROM (
SELECT *, RANK()OVER(PARTITION BY Last_Name, First_Name ORDER BY DATE DESC) as ROW_NUM
FROM TABLE
) AS T
WHERE ROW_NUM = 1

Return first non null value in each column

I am looking to create a summary/rollup by day and customer ID from a table (table is updating from multiple sources currently).
For each customer ID and transaction date, I'm either looking to get a min, max, sum or first non null value in that column for that combination. I have no problem with min, max and sum, but am looking for suggestions on how to best handle the first non null value in a column.
Sample of what my table looks like:
Cust ID Trans Date Housing Housing $ Retail Retail $ Arrival
123 1/1/2019 test1 $500.00 NULL NULL 1/1/2019
123 1/1/2019 NULL NULL product1 $15.00 NULL
1235 5/10/2019 test2 $1,000.00 NULL NULL 5/10/2019
1234 10/15/2019 test2 $1,000.00 NULL NULL 10/15/2019
1234 10/15/2019 NULL NULL product2 $25.00 NULL
Results I'm looking for:
123 1/1/2019 test1 $500.00 product1 $15.00 1/1/2019
1235 5/10/2019 test2 $1,000.00 NULL NULL 5/10/2019
1234 10/15/2019 test2 $1,000.00 product2 $25.00 10/15/2019
SQL tables represent unordered sets. There is no "first value" in a column -- NULL or otherwise -- unless a column specifies the ordering.
However, for your result set, simple aggregation seems sufficient:
select CustID, TransDate, max(Housing), max(Housing$), max(Retail), max(Retail$), max(Arrival)
from t
group by CustID, TransDate;

Multiple Group By and Count

I was wondering if someone could help me with this. Here is a sample set of my data:
FirstName LastName Department Ticket Hours Shift DateWorked Key
Bob Smith Sleeves 23235 4 1 2017-01-01 001
Bob Smith Sleeves 12345 4 1 2017-01-01 001
Jim Bo Sleeves 12345 8 1 2017-01-01 002
Janet Moore Lids 78945 8 2 2017-01-01 003
Jon Bob Lids 45621 1.5 3 2017-01-01 004
Jon Bob Lids 45621 7.5 3 2017-01-01 004
Bob Smith Mugs 12345 8 1 2017-01-02
Jim Bo Lids 99999 8 3 2017-01-02
It should return something like this:
DateWorked Shift Department HeadCount
2017-01-01 1 Sleeves 2 (Bob Smith has two entries but counted as one and Jim Bo makes for 2)
2017-01-01 2 Lids 1 (Janet)
2017-01-01 3 Lids 1 (Jon)
Please note that all departments work all shifts. This is just a sample set. There can be anywhere from none to a hundred per department.
Also one employee could work multiple departments in one day! I don't know how to account for that.
This is what I have. So for this example it's not summing Bob Smith. It's counting him as two.
SELECT Scheduled, Department, [Shift], COUNT(*) as HeadCount
FROM EmployeeTickets
WHERE Scheduled >= '2017-01-01' AND Scheduled < '2017-12-31'
GROUP BY Scheduled, Department, [Shift]
ORDER BY Scheduled, Department, [Shift]
Thank you.
ETA I don't know if it helps but in the table there is a key per entry, so Bob Smith on Jan 1 would have a key for that day. His social security number is also in there. I'm trying to group by one of those somehow.
just use DISTINCT
SELECT Scheduled, Department, [Shift], COUNT( DISTINCT FirstName ) as HeadCount
FROM EmployeeTickets
WHERE Scheduled >= '2017-01-01' AND Scheduled < '2017-12-31'
GROUP BY Scheduled, Department, [Shift]
ORDER BY Scheduled, Department, [Shift]
Of course this will have problem if you have multiple persons with same name. So I hope you have some EmployeeID on your tables, so you can differentiate every employee.
COUNT(DISTINCT EmployeeID)

SQL group by query

I have a a UNION ALL on two result sets. This results in some like below.
TOTALSTABLE
FAMILYNAME-----FIRSTNAME------NUMBER------TOTAL
Brown Dave 1234 500.00
Brown Dave 1234 300.00
Smith Frank 4321 123.00
Smith Frank 4321 456.00
I run the following query...
SELECT TOTALSTABLE.FAMILYNAME,
TOTALSTABLE.FIRSTNAME,
TOTALSTABLE.NUMBER,
SUM(TOTALSTABLE.TOTAL) COMBINEDTOTAL
FROM TOTALSTABLE
GROUP BY TOTALSTABLE.FAMILYNAME,
TOTALSTABLE.FIRSTNAME,
TOTALSTABLE.NUMBER
Which gives me something like...
FAMILYNAME-----FIRSTNAME------NUMBER------COMBINEDTOTAL
Brown Dave 1234 800.00
Smith Frank 4321 579.00
This is what i need. However I need to add an additional column which is null in the result i am attempting to do a UNION ALL on.
Example:
T1
FAMILYNAME-----FIRSTNAME------NUMBER------TOTAL-------DATE
Brown Dave 1234 500.00 01/01/2001
Smith Frank 4321 123.00 01/01/2001
T2
FAMILYNAME-----FIRSTNAME------NUMBER------TOTAL-------DATE
Brown Dave 1234 300.00 NULL
Smith Frank 4321 456.00 NULL
COMBINED (UNION ALL)
FAMILYNAME-----FIRSTNAME------NUMBER------TOTAL-------DATE
Brown Dave 1234 500.00 01/01/2001
Brown Dave 1234 300.00 NULL
Smith Frank 4321 123.00 01/01/2001
Smith Frank 4321 456.00 NULL
I need to get the combined total like in the first example, using the date that isnt null.
Example of desired results.
FAMILYNAME-----FIRSTNAME------NUMBER------COMBINEDTOTAL----DATE
Brown Dave 1234 800.00 01/01/2001
Smith Frank 4321 579.00 01/01/2001
Can anyone tell me what I need to do here? Cheers.
It sounds like you just want
SELECT familyName,
firstName,
number,
SUM(total) combinedTotal,
MAX(date) date
FROM (<<union all query>>)
GROUP BY familyName,
firstName,
number
AS you state, you can try follow code
SELECT * FROM
(SELECT c1, c2, c3 FROM T1
UNION ALL
SELECT c1, c2, c3 FROM T2
) T
WHERE T.c3 IS NOT NULL
GROUP BY T.c1, T.c2, T.c3