Grouping Across a Hierarchy - sql

End Goal: I need to create a financial report that can follow an organization hierarchy but also separate by account type on each level. Ultimately the report will be displayed in crystal reports.
Problem: There are several types of accounts (revenue, expense, liability, etc...). There are also several organizational structures, with a maximum depth of 8 levels. Users need to be able to drill down to each level of the structure, and see sub totals for each account type.
Example
Highest Level
Expense
CEO
Community & Customer Service
Corporate
Engineering
Revenue
CEO
Community & Customer Service
Corporate
Engineering
Level 1 (CEO)
Revenue
WHS
OD
Expense
WHS
OD
The structure continues until you end at the account level, which are grouped by account type.
The structure is stored in an adjacency model.
Structure Columns: Class_id - Class_Name - Parent_ID
Account Columns:
Account_id, Class_id, Account_Type, Budget, Actual
I have no problem navigating and grouping the hierarchy, but my difficulty comes in the grouping of account types within the hierarchy. Any suggestions for solutions in SQL or CrystalReports would be greatly appreciated!

Related

Whether to separate tables if part of a table has a relation to another

I’m learning SQL and have a basic question. I have a transactions table which contains payments and commissions.
A payment:
ID
Date
Amount
Type
Referrer ID
Balance
number
date
number
‘commission’ or ‘payment’
number
number
A commission has the same fields as payments, plus two additional fields: qualified and customerPaymentId
Qualified
Customer Payment ID
boolean (presumably 0 or 1)
number
Whenever a payment is made, the balance decreases, and vice versa whenever a commission occurs.
I have a user table too, where a user can have payments but not commissions. Should I separate the transactions table to be 2 tables (commissions and payments), or keep a single transactions table where the user table has a relation with it (rather than a relation to a separate payments table)?
Any advice or pointers would be great too, thank you.
UPDATE:
Sorry, I don’t think I have been very clear at all here. This is the transactions table, that contains both payments and commissions:
ID
Date
Amount
Type
Referrer ID
Balance
Qualified
Customer Payment Id
1
20/1/22
5.00
COMMISSION
5454
5.00
0
0001
2
28/1/22
4.00
COMMISSION
5454
9.00
0
0002
1
20/1/22
5.00
PAYMENT
5454
4.00
NULL
NULL
1
20/1/22
4.00
PAYMENT
5454
0.00
NULL
NULL
The type of ‘commission’ or ‘payment’ is there to determine whether a record is a commission or payment. A commission would have data for the ‘qualified’ and ‘customer payment id’ columns (but payments wouldn’t).
The Customer Payment ID column actually represents a different type of payment - a payment that a user makes for a product. Conversely, the transaction payment is a different payment that pays towards an affiliate’s balance.
The commission.balance and payment.balance represent an overall balance - commissions add to a user’s total balance while payments deduct from it.
To give some better context, this is for an affiliate system - when a customer buys a product, a payment (different - NOT a transaction payment; it’s from another table) is made, with a Customer Payment ID. An affiliate might have earned a commission from that sale, hence a commission record is made (in the transactions table). The amount they are owed is added to the affiliate’s balance. After 3 months, the commission becomes qualified, and the affiliate is paid their commission at the end of that month, hence a payment is made (a payment from the business to the affiliate), which deducts from the affiliate’s balance. It’s not simple to explain, but that is the gist of it if that makes somewhat sense :) I may not have constructed this the best way.
It's a little difficult to follow what's happening, but it seems you have a bunch of things which have some overlap in their fields but aren't actually the same. But sometimes you want to look at them all together.
I would suggest making separate tables for each kind of thing, and then a create a view to bring them all together.
For example...
create view transactions as
select created_on, amount, 'COMMISSION' as type, balance
from commissions
union all
select created_on, amount, 'PAYMENT' as type, balance
from payments
We use union instead of union all for performance. union removes duplicate rows which means the database has to do more work and operations are slower and more complicated. There are no duplicates in this instance.
Demonstration

Optimized Query in T-SQL

This is commonly faced problem, if you are developing any software solution for any government department. So consider this as critical question to be addressed.
Understanding the scenario
Every government as departments, departments in different cities and each of those are responsible for serving the needs of citizen services. For example, Industry Commiserate. If you want to establish a new manufacturing unit for some products, You are supposed to apply to government department, officials carry out scrutiny and other required verification process. At the end get decision that whether you are eligible for establishing a unit.
Meeting Requirements
To meet above requirement we created database... I'm not going to include everything here but only required tables.
1. GovtOfficers: Goverment officers details having fields
DeptOfficers: contains Department officers,
Citizens: are people like us who file applications,
Applications: are applications submitted by citizen
ApplicationAction: are action taken on different applications...
Now, Our purpose is to find Last Status and Officer name working on particular application...
We'll write it like,
Select *
from Applications A
inner join Citizens C on A.CitizenId=C.Id
left join ApplicationAction AC on A.Id=AC.ApplicationId
left join
(
Select max(Id)
from ApplicationAction
group by ApplicationId
) X on AC.Id=X.Id
The above query fetches the required result and works fine.... But it does not when the data out grows up to 10-20 Lacks, It starts taking time and eventually may timeout.
What could be better approach?
OK, Based on experience gained, I can add ActionId in Application Table as well which will store most recent action taken on that table.... and can solve my problem.
The problem is, I can use above mentioned solution for upcoming projects.. Not the projects that I have completed or I don't have contract.
So I'm not looking for schema change anyway to optimize above query.
do the null application separate
select * from
( Select *,
row_number() over(partition by AC.ApplicationId order by AC.id desc) as rn
from Applications A
join Citizens C
on A.CitizenId = C.Id
join ApplicationAction AC
on A.Id = AC.ApplicationId
) ttt
where ttt.rn = 1

Ruby on rails many-to many relationship

I'm fairly new to Rails so this might seem like a basic question.
I am creating a cinema application and require the tables Bookings and Ticket_Type.
Bookings has the attributes: user_id, showing_id, adult_seats, child_seats, concession_seats.
Ticket_Type will have the attributes: type, price.
This relationship would be many to many, as one booking could have many ticket types, such as by having 2 adults and 2 children, and one ticket type, such as "Child", could have many bookings.
But how do I map this in Ruby on Rails? Or would it be through having a table inbetween called something like Booking_Ticket that would store the booking_id and ticket_type_id?
What I will need my application to calculate, for instance, is the total price of a booking - so if a booking has 2 adults, 1 concession, and 2 children, and in ticket_type an adult costs 7.50, a concession 6, and a child 5, then the total would be 31.
I really don't think that there is a relationship between Bookings and TicketType. TicketType is merely a settings table in your application where you are storing pricing data. Since adult_seats, child_seats, concession_seats are integer values, there is no direct association between the 2 tables.
All you really need the TicketType for is reference on cost. I seems that this table will not hold much data; I would just load that data prior to determining cost of the the booking.

Dimensional Model for Employee Turnover

I am trying to determine the best way to model the scenario of employee turnover for a Dimensional Model. I am not sure if its best to include the Termination_Count and Headcount in the same measure.
I currently have a headcount measure with both termed and headcount:
**Headcount Measure:**
Employee_id
Department
Employee_count
Termed_count
Month
So each individual employee will have a row created for them if they are active during the month or if they are terminated during the month.
How have other people worked with employee turnover issue.
Don't track Headcount and Turnover in the same table, they have different grains.
Headcount: being a semi-aditive measure you need a snapshot fact table counting employees per department, salary level, bureau and whatever other dimensions you need. It should store these values once per day;
Turnover: have a Hire/Fire transaction table with three measures: employees_hired (0/1), employees_fired (0.1) and net_employee_variation (=1/0/+1). On the employee dimension you can have a "date_hired" and "date_left_ as attributes to allow, for example, counting time between the two events.
But you shouldn't mix what is a transaction fact table with a snapshot fact table.

How to design a star schema

I am confused where should I start to design a star schema.
for example
I have tables in database as follows:
Branch(branchNo, bStreetAddress, bCity)
LoanManager(empNo, empName, phone, branchNo)
Customer(custNo, custName, profession, streetAddress, city, state)
Account(accNo, accType, balance, accDate, custNo)
LoanContract(contractNo, loanType, amount, loanDate, empNo, custNo)
I want to design a data-warehouse to analysis the loads
such as :
The total amount of loans in 2008.
For the type of loans with more than 10 loan contracts, the type of loan and the number of contracts
when creating a star schema, what where should I start?
For what I understanding, all the star schemas must have a center, and the center fact table, contains "Measures" and "Relations to other fact tables".
So, is it that, when designing the star schema, we always start from the center,
confirm what are the measure first? and then choose proper relation to another fact table?
But I still have another question, what should we choose to be Measures?
When choosing measures, what question should I ask myself?
The design of a star schema is always driven by the client's business needs. What are the questions asked? How fine-grained should the answers be?
In you example, interesting questions might be "Number of Contracts by Branch or LoanManager" or "Managed sum of Loans by Branch or LoanManager". In this case, Branch and LoanManager would become your dimensions while Count(LoanContract) and Sum(LoanContract.amount) would be your measures. A common additional dimension is time, usually week or quarter.
The schema for answering those questions could look like this:
DimBranch ( branchNo )
DimLoanManager ( empNo )
DimQuarter ( year, qNo ) -- qNo in (1,2,3,4)
DimWeek ( year, weekNo ) -- weekNo in (0..53), depending on business rules
Measures ( branchNo, empNo, year, qNo, weekNo, numContracts, sumLoans )
For the business questions you already posed in your question, the dimensions and measures would be such:
dimension: year, measure: Sum(LoanContract.amount)
dimension: loanType, measure: Count(LoanContract)
Putting those two into the same star schema doesn't make much sense, since they neither share dimensions or measures.