Calculated Query Field ignoring some results - ms-access

I have a calculated field in a query that takes our total revenue per customer and subtracts out total costs per customer to get our margins with that customer. The formula works fine as long as the customer has a cost value but if the customer has no cost, the formula is ignoring that revenues exists and is excluding that customer from the total and the query does not include them in the returned result. Is there a way to fix the formula to include these customers with no costs but still generate revenue?
SELECT [Company Information].[Company Name], ([2 YTD - Customer
Revenues].SumOfSumOfCharge-[2 YTD - Customer Costs].[SumOfTotal Cost])
AS [Customer Margin]

For a query run from within an Access session, you can use Nz to have Access substitute 0 for Null when it computes the difference ...
Nz([2 YTD - Customer Costs].[SumOfTotal Cost], 0)
Alternatively you could use an IIf expression to accomplish the same thing ...
IIf([2 YTD - Customer Costs].[SumOfTotal Cost] Is Null, 0, [2 YTD - Customer Costs].[SumOfTotal Cost])
Support for IIf is built into the db engine, so it is available for any Access query. Nz is an external (VBA) function which the db engine can use within an Access session. So the IIf approach should theoretically be faster, but may not be noticeably faster in practice.

Related

Microsoft Access - Group By Condition

I have a column in one of my tables called revenue.
The revenue values can be positive or negative.
Say there are revenue values such as +100 and -100.
Is there a way I can group by revenue, such that it does not read the sign? Meaning it reads -100 and +100 the same?

MYSQL SUM, value has to change on condition

I have a "CONTRACTS" table in which the user can select whether a Contract is "ANUAL" or "MONTHLY" (working on MariaDB/phpmyadmin)
The data is stored in the following manner:
CONTRACT
PERIOD
CICLE
SALE PRICE
CATEGORY
001
1
YEARLY
12000
CAT1
002
1
MONTHLY
1000
CAT2
I want to make a report that tells me the SUM of monthly contracts by CATEGORY
RIGHT NOW, THIS QUERY BELOW WORKS but its useless, since its doing SUM of "yearly" contracts along with monthly contracts
SELECT SUM(contracts.salesprice), `categories`.*
FROM `contracts`
LEFT JOIN `categories` ON `contratos`.`cat_id` = `categories`.`id_cat`
GROUP BY categorias.descripcion_cat;1
I'm a newbie and so far I was fine with INSERT, SELECT, UPDATE, DELETE;
I tried reading all documentation about CASE or IF, but I cant figure how to tell mysql to SUM based AND calculate on conditions
when CICLE = YEARLY then SALEPRICE /12 (to get the monthly value)
You were on the correct track with CASE.
The following code snippet will convert your yearly sales prices into monthly:
SUM(
CASE
WHEN contracts.cicle = 'YEARLY' THEN (contracts.salesprice / 12)
WHEN contracts.cicle = 'MONTHLY' THEN contracts.salesprice
ELSE 0
END
)
To use it in your query, simply replace your SUM(...) with that one.
To explain what it is doing, the CASE statement has several WHEN conditions. It uses the value of the first one that is true, if none are true, it will use the ELSE value (which you can change if you don't like 0). All of those resulting values are then summed up with SUM.
The benefit of CASE over IF is that CASE can be expanded as needed if you need more calculations for bi-annual, quarter, etc.

What criteria can I use in MS Access to have monthly sales data appear only if it is between specified start and end dates?

I am using MS Access 2013.
The query I am working on is called "Bookings Query." Within the Bookings Query, I have two tables (Initialization and Bookings) joined together by Assignment Code. The Initialization table contains data for Sales Reps and their assignments with start/end dates and the Bookings table contains data for assignments and their monthly quota.
I need to have monthly quota data from the Bookings table only appear if it's within the Start and End Dates which come from the Initialization table. For Example: if we look at Assignment "ABC", and quota is $150,000 for January but the start and end dates for "ABC" are 2/1/21 - 12/31/21, then I need January to be $0 since quota for this assignment does not start until February.
Thanks in advance. It's a bit confusing I know.
Below is a sample I have used regularly
SELECT DISTINCTROW Accounts.AccountNumber, Accounts.AccountName, Sum(Transactions.[DEBIT AMOUNT]) AS DEBIT, Sum(Transactions.[CREDIT AMOUNT]) AS CREDIT
FROM Accounts LEFT JOIN Transactions ON Accounts.AccountID = Transactions.AccountID
WHERE (((Transactions.TransactionDate)>=[forms]![Report Date Range]![Beginning Rpt Date] And (Transactions.TransactionDate)<=[Forms]![Report Date Range]![Ending Rpt Date]))

How do I subtract two declared variables in MYSQL

The question I am working on is as follows:
What is the difference in the amount received for each month of 2004 compared to 2003?
This is what I have so far,
SELECT #2003 = (SELECT sum(amount) FROM Payments, Orders
WHERE YEAR(orderDate) = 2003
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate));
SELECT #2004 = (SELECT sum(amount) FROM Payments, Orders
WHERE YEAR(orderDate) = 2004
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate));
SELECT MONTH(orderDate), (#2004 - #2003) AS Diff
FROM Payments, Orders
WHERE Orders.customerNumber = Payments.customerNumber
Group By MONTH(orderDate);
In the output I am getting the months but for Diff I am getting NULL please help. Thanks
I cannot test this because I don't have your tables, but try something like this:
SELECT a.orderMonth, (a.orderTotal - b.orderTotal ) AS Diff
FROM
(SELECT MONTH(orderDate) as orderMonth,sum(amount) as orderTotal
FROM Payments, Orders
WHERE YEAR(orderDate) = 2004
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate)) as a,
(SELECT MONTH(orderDate) as orderMonth,sum(amount) as orderTotal FROM Payments, Orders
WHERE YEAR(orderDate) = 2003
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate)) as b
WHERE a.orderMonth=b.orderMonth
Q: How do I subtract two declared variables in MySQL.
A: You'd first have to DECLARE them. In the context of a MySQL stored program. But those variable names wouldn't begin with an at sign character. Variable names that start with an at sign # character are user-defined variables. And there is no DECLARE statement for them, we can't declare them to be a particular type.
To subtract them within a SQL statement
SELECT #foo - #bar AS diff
Note that MySQL user-defined variables are scalar values.
Assignment of a value to a user-defined variable in a SELECT statement is done with the Pascal style assignment operator :=. In an expression in a SELECT statement, the equals sign is an equality comparison operator.
As a simple example of how to assign a value in a SQL SELECT statement
SELECT #foo := '123.45' ;
In the OP queries, there's no assignment being done. The equals sign is a comparison, of the scalar value to the return from a subquery. Are those first statements actually running without throwing an error?
User-defined variables are probably not necessary to solve this problem.
You want to return how many rows? Sounds like you want one for each month. We'll assume that by "year" we're referring to a calendar year, as in January through December. (We might want to check that assumption. Just so we don't find out way too late, that what was meant was the "fiscal year", running from July through June, or something.)
How can we get a list of months? Looks like you've got a start. We can use a GROUP BY or a DISTINCT.
The question was... "What is the difference in the amount received ... "
So, we want amount received. Would that be the amount of payments we received? Or the amount of orders that we received? (Are we taking orders and receiving payments? Or are we placing orders and making payments?)
When I think of "amount received", I'm thinking in terms of income.
Given the only two tables that we see, I'm thinking we're filling orders and receiving payments. (I probably want to check that, so when I'm done, I'm not told... "oh, we meant the number of orders we received" and/or "the payments table is the payments we made, the 'amount we received' is in some other table"
We're going to assume that there's a column that identifies the "date" that a payment was received, and that the datatype of that column is DATE (or DATETIME or TIMESTAMP), some type that we can reliably determine what "month" a payment was received in.
To get a list of months that we received payments in, in 2003...
SELECT MONTH(p.payment_received_date)
FROM payment_received p
WHERE p.payment_received_date >= '2003-01-01'
AND p.payment_received_date < '2004-01-01'
GROUP BY MONTH(p.payment_received_date)
ORDER BY MONTH(p.payment_received_date)
That should get us twelve rows. Unless we didn't receive any payments in a given month. Then we might only get 11 rows. Or 10. Or, if we didn't receive any payments in all of 2003, we won't get any rows back.
For performance, we want to have our predicates (conditions in the WHERE clause0 reference bare columns. With an appropriate index available, MySQL will make effective use of an index range scan operation. If we wrap the columns in a function, e.g.
WHERE YEAR(p.payment_received_date) = 2003
With that, we will be forcing MySQL to evaluate that function on every flipping row in the table, and then compare the return from the function to the literal. We prefer not do do that, and reference bare columns in predicates (conditions in the WHERE clause).
We could repeat the same query to get the payments received in 2004. All we need to do is change the date literals.
Or, we could get all the rows in 2003 and 2004 all together, and collapse that into a list of distinct months.
We can use conditional aggregation. Since we're using calendar years, I'll use the YEAR() shortcut (rather than a range check). Here, we're not as concerned with using a bare column inside the expression.
SELECT MONTH(p.payment_received_date) AS `mm`
, MAX(MONTHNAME(p.payment_received_date)) AS `month`
, SUM(IF(YEAR(p.payment_received_date)=2004,p.payment_amount,0)) AS `2004_month_total`
, SUM(IF(YEAR(p.payment_received_date)=2003,p.payment_amount,0)) AS `2003_month_total`
, SUM(IF(YEAR(p.payment_received_date)=2004,p.payment_amount,0))
- SUM(IF(YEAR(p.payment_received_date)=2003,p.payment_amount,0)) AS `2004_2003_diff`
FROM payment_received p
WHERE p.payment_received_date >= '2003-01-01'
AND p.payment_received_date < '2005-01-01'
GROUP
BY MONTH(p.payment_received_date)
ORDER
BY MONTH(p.payment_received_date)
If this is a homework problem, I strongly recommend you work on this problem yourself. There are other query patterns that will return an equivalent result.
I think this is the problem:
In #2003 and #2004, you select only the sum. And even if you group by the month you still select one column i.e. each row does not say what month it is select for. So when you try to subtract SQL asks which row in #2003 should be subtracted from #2004.
So I think the solution is to select the month with the sum and do the subtract later based on the month.

How can I write an MDX statement or query that selects the clients who paid last month but have not paid this(Current Month) month?.

How can I write an MDX statement or query that selects the clients who paid last month but have not paid this(Current Month) month?. I have a data cube designed and deployed on Microsoft SQL Server Analysis Services R 2. I have a customer dimensions and a fact table.
Please help.
I assume you have a [Time] dimension, and a measure that contains a value if the client has paid. I think the Filter() function will help you reduce a set of all clients down to just the clients that you're interested in.
SELECT {Filter({[Client].[SomeLevel].members}, ([Time].[LastMonth], [Measures].[whatever]) > 0 AND ([Time].[ThisMonth], [Measures].[whatever]) = 0} ON ROWS, {[Measures].[whatever]} ON COLUMNS FROM [CubeName]
You trouble might be deciding what to use in place of where I wrote [Time].[ThisMonth] - see other answers here on StackOverflow for selecting 'current' dates.
First of all, you have to identify the current month and the last month. One way to do it is compute it using the VBA!Date function.
So if your dates are stored in the format 12/31/2014 and assuming you have a measure Payment and a Date dimension with a Year-Quarter-Month-Date hierarchy, the below code can help you.
WITH MEMBER [Measures].ValueThisMonth AS
(
[Date].[Year-Quarter-Month-Date].CURRENTMEMBER.PARENT,
[Measures].[Payment]
)
MEMBER [Measures].ValueLastMonth AS
(
[Date].[Year-Quarter-Month-Date].CURRENTMEMBER.PARENT.LAG(1),
[Measures].[Payment]
)
SELECT [Client].[Client Name].MEMBERS
HAVING ISEMPTY([Measures].ValueThisMonth)
AND NOT(ISEMPTY([Measures].ValueLastMonth))
ON 0
FROM [Your cube]
WHERE
StrToMember("[Date].[Year-Quarter-Month-Date].[Date].&[" + FORMAT(VBA![Date](), "MM/dd/yyyy") + "]" + "]")
If instead you would like to pass this "current" value from the front end, use a parameter in the WHERE clause.