MySQL: Select Results Not As Expected: Newbie Alert - mysql

I used SQL back in the 90s and starting to get back into it for a project at work.
I want to store departmental budget data so I can run queries and use it in Power Bi.
I have a simple table with columns for the department (fund) and corresponding monthly expense info. I am trying to run a query where I can see the expenses for one fund under the supplies account -- can't get it to work. I know I will probably kick myself when I see the solution so here we go...
Select * FROM expenses
FundID Fund FY Account January February March April May June July August
9999 tester 2019 Grant Assistance to INT'L Individuals 1 2 3 4 5 6 7 8
9999 tester 2019 Grant Assistance to INT'L Organizations 21 22 23 24 25 26 27 28
9999 tester 2019 Grant Assistance to U.S. Individuals 31 32 33 34 35 36 37 38
9999 tester 2019 Grant Assistance to U. S. Organizations 41 42 43 44 45 46 47 48
9999 tester 2019 Salaries, etc. 4500 4500 4500 4500 4500 4500 4500 4500
Table = expenses
Columns
FundID, Fund, FY, Account, January, February… December
SELECT *
FROM expenses;
— results in all data from sample table (as expected)
SELECT *
FROM expenses
WHERE Fund = 'associate1';
— results in all data for ‘associate1’ (as expected)
SELECT *
FROM expenses
WHERE Fund = 'associate1' AND Account = 'Supplies';
— results in alert advising ‘empty result set (i.e. zero rows) (not expected)
—- rows/record is populated
Expected:
FundID Fund FY…. December populated with associate1’s data for supplies.
I also attempted query: SELECT * FROM expenses WHERE Account = ‘Supplies’; (Nothing)

Related

MySQL - Connect three different tables in transposed fashion

I have three tables:
business:
id name
1 Charlie's Bakery
2 Mark's Pizza
3 Rob's Market
balanco_manual:
id business_id year unit
012 1 2015 ones
123 1 2014 tens
364 2 2014 cents
conta_balanco:
id conta balanco_id valor
412 12.3 012 12324
344 12.5 012 54632
414 14.1 364 344122
789 12 364 2312415
646 12 123 342
I need to combine them all in the business table and make them look like this:
business:
id name 12.3-2015 12.5-2015 11.56-2015 12-2014 2015-unit 2014-unit
1 Charlie's Bakery 12324 54632 NaN 342 ones tens
2 Mark's Pizza NaN NaN NaN 2312415 NaN cents
3 Rob's Market NaN NaN NaN NaN NaN NaN
Explaining a little bit further: the business table has basic registries about the businesses, balanco_manual has yearly information of each one of those businesses and conta_balanco has details of the yearly information in balanco_manual.
Trying to put that last table into words:
- First I need to join business with balanco_manual, combining the "id" column in business with the "business_id" column in balanco_manual. Note that I combine unit and year in one single column named "[year]-unit". Let's call this table "new_business" to make it easir to understand
- After, I need to combine "new_business" with conta_balanco in a similar way we did with the "unit" column. Each "conta" should be combined with the year and become a column "conta-[year]".
I'm quite a beginner with SQL and I'm having interesting difficulties. Could someone help me to crack that out?

Programming Rookie - Limiting From 2 Tables

I am attempting to determine "First Time Givers", people who gave in FY2015 but never given before. I also need to ignore users who gave for a certain reason (appealCode).
Below is example of some of the fields my tables have and what information needs limited.
**FundLedger**
Account ID EntryAmount GiftReceivedDt AppealCode
1000 $500 7/1/2014 1
1000 $500 2/2/2002 2
2000 $25 8/1/2014 1
2000 $25 9/1/2014 1
3000 $100 10/1/2014 1
4000 $1,000 11/1/2014 2
**ConstituentTotals**
ConstituentID FirstTransactionDate LastTransactionDate CashAmount
1000 2/2/2002 1/1/2014 $1,000
2000 3/1/2014 4/1/2014 $50
3000 5/1/2014 5/1/2014 $100
4000 11/1/2014 11/1/2014 $1,000
What I need is to find the number of constituents who gave between 6/1/2014 and today, who have never given before, and the gift was not given to AppealCode 2.
So the number I need from the sample information is '2'.
**Information Needed**
ConstituentID CashAmount FirstTransactionDate LastTransactionDate AppealCode
2000 $50 3/1/2014 4/1/2014 1
3000 $100 5/1/2014 5/1/2014 1
As of now I can either get the number of people who gave if I ignore the AppealCode, or I can get the AppealCode limited but I get ALL transactions of the giver.
Currently at this stage, it pulls the count 77,000 times, one for each entry in the Ledger.
'SELECT
Number_Of_New_Donors = ( SELECT COUNT(a.ConstituentID)
From dbo.FundConstituentTotals a
RIGHT JOIN dbo.FundLedger b
ON a.ConstituentID = b.AccountID
WHERE (a.FirstTransactionDT between '6/1/2014' and '5/31/2015'
AND a.CashAmount > '0'
AND a.GivingYear = '2015'
AND A.GivingYear !< '2015')
AND (b.GiftReceivedDt between '6/1/2014' and '5/31/2015'
AND b.RecordTypeID != '0'
AND b.RecordTypeID != '-1'
AND b.RecordTypeID != '2'))
FROM FundConstituentTotals'
Suggested Response Results:
ConstituentID FundConstituentTotalID ConstituentID GivingYear PledgeAmount CashAmount NonCashAmount FirstTrans
49427 77314 49427 2015 0 25 0 1/13/2015
49427 77314 49427 2015 0 25 0 1/13/2015
49427 77314 49427 2015 0 25 0 1/13/2015
49427 77314 49427 2015 0 25 0 1/13/2015
Just found that the data is innacurate, FirstTransactionDate does not provide the date of the first transaction, just the date the transaction begin being posted to the ledger (SOMEONE MESSED THIS UP IN THE PAST). I will have to use GiftReceivedDate between DATES, and find a way to remove people if they have dates prior to 2014.
SELECT Number_Of_New_Donors = ( SELECT COUNT(a.ConstituentID)
From dbo.FundConstituentTotals a
LEFT JOIN dbo.FundLedger b
ON a.ConstituentID = b.AccountID
AND a.LastTransactionDate = b.GiftReceivedDt
WHERE a.FirstTransactionDT between '2015-01-01' and '2015-05-31'
AND b.AppealCode != 2)
This seems to do what you want. FirstTransaction is this year (since it is the first, there can't be previous ones), and appeal code isn't 2. What is the rest of your code trying to do?

Grouping Data in MS Access 2010 based on multiplication

I am a new user to MS Access.
My table has 2 columns: a column for number of days which goes from 0 to 150+ and a column for principal paid (any number say 858576)
There are over 70000 rows.
Row 1 says 70 days and principal paid as 898956
Row 2 says 68 days and principal paid as 13751
Row 3 says 190 days and principal paid as 397159
Row 4 says 11 days and principal paid as 56978
Row 5 says 29 days and principal paid as 9078910
I want a query to return records from 0-30 days, 30-60 days, 60-90 days, 90-120 days, 120-150 days and 150 above and showing sum of principal against each group mentioned above. Can it be done? If so, how?
If you know the maximum number of your days in the table and criteria for dividing into groups, you could try by using the case:
SELECT
SUM(principal_paid),
days_range
FROM
(
SELECT
principal_paid,
CASE days
WHEN BETWEEN 0 AND 30
THEN '0-30'
WHEN BETWEEN 31 AND 60
THEN '31-60'
WHEN BETWEEN 61 AND 90
THEN '61-90'
WHEN BETWEEN 91 AND 120
THEN '91-120'
WHEN BETWEEN 121 AND 150
THEN '121-150'
ELSE 'over 150'
END AS days_range
FROM
yourtable
)
as T
GROUP BY
days_range

MS Access "double counting" in a query of queries

Apologies if this question is a bit long, but I wanted to explain in detail what it is I am trying to do.
I am developing a database in MS Access 2010/Windows 7 which analyses and reports on incidents (e.g. faults) in an organisation. An incident is reported as beginning at a particular date/time in a particular location for a particular duration. An incident may occasionally cause one or more "live resilience outages" (LRO) which will have the same start-time but can be in different locations and have different durations. So for example a router going out of service in the central technical area for 600 sec might cause live outages of 60 sec and 30 sec in studios 5 and 6 respectively.
I need to report on three date ranges: the month in question, the previous month and the (financial, beginning in April) year to date. So for example the report for March 2012 would consider the periods 01 Mar 2012 - 31 Mar 2012 (month), 01 Feb 2012 - 29 Feb 2012 (previous) and 01 Apr 2011 - 31 Mar 2012 (YTD).
These dates are correctly calculated in a form called ReportCentre. I have three queries to return the LROs for the different date ranges: QueryLROMonth, QueryLROPrevious and QueryLROYTD all of which work properly in isolation (i.e. return the correct values). So for example QueryLROMonth is defined as
SELECT lro.*
FROM lro INNER JOIN incidents ON lro.pid = incidents.id
WHERE (((incidents.begin) Between [Forms]![ReportCentre].[StartMonth] And
[Forms]![ReportCentre].[EndMonth]));
which returns the expected values:
id pid duration facility
6 681 30 23
7 686 857 23
8 735 600 25
9 738 600 25
as does the YTD query
id pid duration facility
1 100 120 25
2 366 5 25
3 380 460 1
4 505 341 23
5 622 0 29
6 681 30 23
7 686 857 23
8 735 600 25
9 738 600 25
20 1297 50 1
So far so good, but now the bit that's got me puzzled. I am trying to design another query which takes the output of the three LRO queries (and some other data), groups it all by facility and calculates things like availability. If I design a totals query and include the Facilities table (for the facility name) and the QueryLROMonth query e.g.
SELECT facilities.facility, Count(QueryLROMonth.id) AS lrocountmonth, Sum(QueryLROMonth.duration) AS lrosecondsmonth
FROM QueryLROMonth INNER JOIN facilities ON QueryLROMonth.facility = facilities.ID
GROUP BY facilities.facility;
This works fine and produces what I expect.
facility lrocountmonth lrosecondsmonth
HQ3 2 887
HQ5 2 1200
but as soon as I introduce the YTD query:
SELECT facilities.facility, Count(QueryLROMonth.id) AS lrocountmonth, Sum(QueryLROMonth.duration) AS lrosecondsmonth, Count(QueryLROYTD.id) AS lrocountytd, Sum(QueryLROYTD.duration) AS lrosecondsytd
FROM QueryLROYTD INNER JOIN (QueryLROMonth INNER JOIN facilities ON QueryLROMonth.facility = facilities.ID) ON QueryLROYTD.facility = facilities.ID
GROUP BY facilities.facility;
for some reason stuff starts being counted reported wrongly. Specifically the two Count columns are multiplied together and so lrocountmonth and lrosecondsmonth are both multiplied by lrocountytd. Similarly lrocountytd and lrosecondsytd are both multiplied by lrocountmonth.
facility lrocountmonth lrosecondsmonth lrocountytd lrosecondsytd
HQ3 6 2661 6 2456
HQ5 8 4800 8 2650
What am I doing wrong? How do I prevent this entanglement?
Your [QueryLROMonth] and [QueryLROYTD] queries each return multiple rows per Facility, but because you are effectively JOINing them on just the Facility_ID you are producing an OUTER JOIN of sorts. For example, if for a given Facility your [Month] query contains 3 rows and your [YTD] query contains 6 rows then your JOIN on Facility_ID alone will produce 18 rows.
You'll want to create aggregation queries that "roll up" the Monthly and YTD numbers by Facility first, so they each have only one row per Facility. You can then use them in your final query to produce the report.
Troubleshooting tip: If your aggregation queries are producing strange results try removing the GROUP BY parts so you can see the underlying rows that are being aggregated.

SQL: Aggregate function returning 0's when using WHERE filter

I have a table with 10 columns listing results of a marketing campaign including person name, date, residence area, request, and response.
The request column is always a number, indicating the number of survey requests we've sent a specific person.
The response column is a number from 0 to X, representing the number of surveys a person has responded to take.
Now, when I look through the actual table, there are probably around 10% response rate. With lots of non-zero entries in the response column.
However, when I write an aggregate function like this:
SELECT person, date, SUM(requests), SUM(response)
FROM analytics.SurveyResults0304
WHERE group_type = 'Youth'
GROUP BY person, date;
I get a correct number for SUM(requests), but I get a big fat "0" for SUM(response)?
It's the same for all 3 group types. It returns a 0 for SUM(response)
Update: it works fine when I don't include the group_type filter, but how come I can't use it with the WHERE filter?
Thanks!!!
EDIT2: Sample Table
Person Date Group_Type Requests Response Neighborhood FirstName
-------- -------- ----------- -------- -------- ------------ ---------
Nixon 3/3/2013 Youth 3 3 Chinatown Richard
Clinton 3/3/2013 Youth 4 0 Gunhill Bill
Mao 3/3/2013 Youth 5 0 Berryville Chairman
Nixon 3/4/2013 Youth 17 2 Townsford Richard
Gates 3/3/2013 Elderly 41 5 Chinatown Bill
Gates 3/4/2013 Elderly 0 0 Chinatown Bill
Gates 3/5/2013 Elderly 0 0 Chinatown Bill
Gates 3/6/2013 Elderly 0 0 Chinatown Bill
For example
When I do:
SELECT SUM(requests), SUM(response)
FROM analytics.SurveyResults0304
WHERE group_type = 'Youth';
It returns 70 for request, and 0 for response across the board.
Your code seems to be working. See SQL Fiddle built from your data sample.
May be you have extra spaces and/or tabs in your Group_Type column?
PERSON DATE SUM(REQUESTS) SUM(RESPONSE)
--------------------------------------------------------
Clinton March, 03 2013 00:00:00+0000 4 0
Mao March, 03 2013 00:00:00+0000 5 0
Nixon March, 03 2013 00:00:00+0000 3 3
Nixon March, 04 2013 00:00:00+0000 17 2