Run a query to check consistency in SQL Server - sql

I need some help with a SQL query and logic in general. (Using MSSQL Server)
I need to check the consistency of payments at certain retailers over a period of three months.
So I've got a table with all my transactions and the following columns:
TransactionID , AccountNumber , Retailer, Date .... (few other irrelevant ones)
Now one Accountnumber could have many transaction IDs. (One account could decide to make several payments during one month).
I have 4 unique retailers' ids, let's call them (101,102,103,104)
Now for consistency I want to get the following data:
The count of transactions where there was only one payment per account for the month at each retailer.
So I'd have:
| # Payments For Month | Retailer | Number of Transactions
| 1 Payment | 101 | 5000
...
But I also want to see how many transactions there were from accounts that made payments at multiple retailers
So I'd want something like:
| 2 Payments | 102 & 104 | 20
Which would mean that an account made 20 payments at retailer 102 & 104.
I don't as much care about how many accounts, more the amount of transactions.
I also want it broken down by month, but I've decided to do a seperate query for each month.
I've imported the data into a local DB on my personal laptop so I could go crazy, so I'll be able to try any method.
The goal of this query is to check the consistency of payments by people (accounts) at certain retailers. How many transactions do they loyally make at one retailer every month, how many transactions are there where they've gone to two retailers? or three? or all four?

Related

Update historical results from wrong recurrent query

Hi I am wondering how to go about the following situation: I have a recurrent query (PostgreSQL DB V12 instance) which runs and inserts data into a table for customer volume with 6 different metrics on a daily basis, creating a snapshot of the dataset over time:
26/03/2021| Active Linked Customers | 10
26/03/2021| Customers where all accounts have positive consent | 20
26/03/2021| Customer with accounts with a mixture of positive consent and > 90 days | 30
26/03/2021| Customers who have all accounts > 30 days | 40
26/03/2021| Customers who have ever connected >=1 account | 50
26/03/2021| Customer record created but customer never connected an account | 5
25/03/2021| Active Linked Customers | 7
25/03/2021| Customers where all accounts have positive consent | 9
25/03/2021| Customer with accounts with a mixture of positive consent and > 90 days | 30
25/03/2021| Customers who have all accounts > 30 days| 40
25/03/2021| Customers who have ever connected >=1 account | 50
25/03/2021| Customer record created but customer never connected an account | 4
...
I have now realised that I need to tweak / fix a where clause of my query that has been generating all results for a couple of months now. This fix is to exclude accounts that have been deleted already from the system, I just need to add the following clause:
where deleted_date is not NULL
The query has been built on 6 different CTEs that feeds the table above on a daily basis. The fix is for future results is straightforward, but how to "fix" the historical data and exclude deleted accounts from the results? Is there a way to reverse engineer the results and "go back in time" to tweak the query and rerun for the last couple of months? Or even some clever data analysis to get around this? Any ideas / suggestions?

SQL Database Design for monthly issued coupons

I'm struggling with a database schema for a problem I'm having.
Let's say I own a business that sells monthly services (cleaning) to different companies.
However, I give companies monthly saveable 'coupons' that act like a reduction (of 5 dollars) based on their amount of users.
Example:
It's april 2018
Company XYZ has to pay 1.000 dollars for their monthly cleaning services by my business.
XYZ, has 5 employees, so they will have 5 coupons for the month of april.
HOWEVER, since coupons can be saved (for a period of 2 months), company XYZ will not use the coupons of only april, but also of march (since they didn't use any that month and february coupons are already used up).
Result:
10 coupons are used on their april invoice (5 of march, 5 of april):
total amount to pay 950 dollars
My thing is that I want to automate this. With one click on the button, my system will have to check:
How many users there are
If there are any unused coupons from last 2 months (and use those first if they exist)
Apply coupons to their invoice.
I want to design this first in a database but i'm struggling:
This is my design
Company
CompanyID
Name
User
UserID
CompanyID
UserID
Now I'm struggling with the coupon design, how can I develop this so that I can automise my problem.
I will need to save coupons per company per month.
My idea is to do it like this:
Company_Month_Coupon
CompanyID
Coupon_Count
Month
I wasn't sure if i could do this in one table and i'm not so sure with the following problem:
what if my program user decides to cancel an invoice, how would my system know from which month the coupons came?
What design would be adviced in a coupon-sharing system?
Any advice to tackling this problem would greatly appreciated.
I would go with your idea and have 2 more tables: Invoices and Invoices_UsedCoupons
Invoices:
ID (Primary key)
CompanyID
Month
Status (to set a cancelled status on your invoice if you don't want to delete from the DB)
Invoices_UsedCoupons:
InvoiceId (foreign key to Invoices table)
Coupon_Count
Month (this field is for the used coupons from Company_Month_Coupon table)
The reasons for this:
We should still store the issued coupons (in your Company_Month_Coupon table) because for each month, the number of employees may change. It means that you have to keep track of the issued coupons whenever the number of employees changes.
With Invoices and Invoices_UsedCoupons table, you could easily calculate the actual used coupons & the remaining coupons.
what if my program user decides to cancel an invoice, how would my
system know from which month the coupons came?
All the information is available in Invoices and Invoices_UsedCoupons tables. If you want to reclaim coupons after cancelling the invoice, it's also easy to do.
"I will need to save coupons per company per month."
Maybe you can do the opposite. In the database does not store coupons that can be used, but only those that are actually used, for example in the table "used_coupons"
The idea is that the coupons are given up by default, so it makes no sense to store them. Only need to save the used coupons.
At checkout you need to find out how much users is in the company and how many "used coupons" is saved in the last two months.
If X coupons are returned then from the "used_coupons" table you need to delete the latest X coupons.

SQL SUM expression and Lock

I have a problem with right SQL solution.
Current situation:
My database contains table with bank transactions (credit and debit).
Credit transactions are signed as posivitive amount (+), and
debit transactions as negative amount (-).
Application which uses the DB is a multiuser webapp, so Transactions Table contains many rows, which reference to different users.
Some webapp actions need to check actual balance of logged user, using Transactions table and save debit Transaction (action price).
I think about architecture of this mechanism and have some questions:
Is it a good idea to calculate balance as a SUM of Transactions credits and debits each time user requests? I know it may be inefficient for db. Maybe should I save a snapshot somewhere?
How to ensure data cohesion when one user checks ""balance"" as a SUM of credit/debit transactions, and another user in the same time saves debit transaction (because he/she was faster)? I think about a pessimistic lock but what should I lock? I know that lock with aggregation (SUM) may be impossible on Postgresql (database which I use)."
Sorry for my English, I hope my problem is understandable. :)
I would consider EITHER:
Storing a balance on the account record, along with the date for which the balance is accurate.
Getting the current balance is a matter of reading the account balance, and then including any transactions since that date.
You can have a scheduled job that recalculates and timestamps that balance at an hour past midnight.
OR (and this is my preferred solution):
Every time a transaction or batch of transactions is loaded, lock the relevant account records and update them with the values from the insert as part of the same transaction.
This has the advantage of serialising access to the account, which can then help with determining whether a transaction can go ahead or not because of decisions based on the balance calculation.
If you want to avoid having the balance on the user account, something that could have a better performance, the approach I would experiment would be:
Each transaction would be related to only one account.
Each transaction would have the account balance after that transaction.
Therefore, the last transaction for that account would have the current balance.
Ex.:
TransactionId | AccountId | Datetime | Ammount | Balance
1 | 1 | 7/11/16 | 0 | 0
2 | 1 | 7/11/16 | 500 | 500
3 | 1 | 7/11/16 | -20 | 480
4 | 1 | 8/11/16 | 50 | 530
5 | 1 | 8/11/16 | -200 | 330
This way you would be able to get the account balance (last transaction with that accountId) and you would be able to provide a better view into the balance change over time.

How to model and define a fact that can have multiple values for a dimension in an ssas cube

I am encountering an issue in which I have sales which can be part of multiple promotions. I am trying to use a sales fact table which will have multiple rows for sales in multiple promotions. Thus, the cube can only accurately be used to aggregate sales within a promotion, not across promotions.
e.g., here are a couple of rows that could appear in the fact table:
saleid sku sales_date promotion_id revenue
1 123 1-1-2013 1 10
1 123 1-1-2013 2 10
This is one sale which gave the company revenue of $10, but it was part of two different promotions. I want to give users the ability to sum sales for promotion 1, and sales for promotion 2, but not for all promotions at the same time (which would indicate $20 of sales overall).
I think that this should be able to be done in SSAS, but I can't figure out how to do it. Ideally the cube would be defined so that the user can only use it in conjunction with the promotion dimension (and other dimensions as desired), but I'd settle for defining the facts so that they cannot be summed across promotions.
thanks, --sw

How to create view to filter out certain results and group it in Oracle Reports?

I'm actually working on Oracle reports. One of the situation I have is to create a parameter for the reports which is type of fees. I have a table called type_of_fees and one of the column is called type_of_fees
I have several records such as:
monthly rental 1
monthly rental 2
monthly rental 3
1 month deposit
2 months deposit
Aircond charges
Utility
1 month advance
-weekly rental
For the parameter, I would like to have a list of values to choose from which I intend from the dropdown:
Monthly Rental
Deposits
Airconditioning
Utilities
Others
So I would like when user select monthly rental it will show types of monthly rental I got in the table _onthly rental 1,monthly rental 2, monthly rental 3.
I would also like if other records such as the 1 month advance and weekly rental to be put under Others when selected. Now,if I'm not mistaken, I'm going to have to create a view to make things easier
I would imagine needing columns like SELECTION_TYPE and TYPE_OF_FEES.
how would i insert custom records such for the SELECTION TYPE which will show the appropriate type of fees?
example of view intended:
----------------------------------
selection_type | type_of_fees |
----------------------------------
Monthly Rental | monthly rental 1
----------------------------------
Monthly Rental | monthly rental 2
----------------------------------
Monthly Rental | monthly rental 3
----------------------------------
Deposits | 1 month deposit
----------------------------------
Deposits | 2 months deposit
----------------------------------
Airconditioning | Aircond charges
----------------------------------
Utilities | Utility
----------------------------------
Others | 1 month advance
----------------------------------
Others | weekly rental
----------------------------------
How do I create this? especially the part to create data for the selection_type column. I'm not very familiar in creating views.
I have no problem querying out the data I intend to use but I just need to create the view so that I can use the selection_type to query out things easier:
SELECT DISTINCT TYPE_OF_FEES FROM TYPE_OF_FEES
WHERE TYPE_OF_FEES LIKE '%deposit%'
By the way I'm on Oracle. Please if anyone could explain and help.
I am going to assume you are referring to Oracle Reportwriter / Reportbuilder the product bundled with Oracle Forms?
Oracle Reports you have to start with the basics.
Create the report to select all data regardless of selection_type.
This will allow you to concentrate on the structure of the query and the structuring of the report. It's quite crucial to get the structure of your report correct and use this as a basis for the report wizard to generate the report for you. You then customize the generated report accordingly.
Once you have the structure pinned down - create your parameter form and add your parameter(s) into query.
You are probably looking to create two LOV parameter fields with the first being selection_type and the second being type_of_fees. The latter being dependent on the value entered in the first.
Oracle Reports Parameter Form documentation
I'm going to answer my own question since i have found a way, to create a view with that particular selection_type for each type_of_fees i can use CASE WHEN.
using that i can construct the view as i want with new columns.