"Totals" Query: show last non-blank string - sql

I have a totals query (one where I clicked the totals button, and it has "group by" columns) in Access 2007. Most of the columns are fine... group by columns, max columns, min columns, etc. For some of them though, I want to extract only the last non-blank (not "" or null) value of a string column.
Here's a sample of what my SQL looks like:
SELECT Min(Duplicates.AttendedODBefore) AS AttendedODBefore,
Min(Duplicates.ContactByPost) As ContactByPost,
Last(Duplicates.PlannedStart) As PlannedStart,
Min(Duplicates.AccessibilityRequirements) AS AccessibilityRequirements,
Last(Duplicates.UcasNumber) As UcasNumber
-- ^^^^
FROM DuplicateStudents As Duplicates
GROUP BY
Duplicates.ID
The expression highlighted is the one I want changing to the last non-blank field. Is there an Access-specific or plain SQL expression which will do this?
Edit: Turns out that Min() and Max() work on string values and ignores null values, taking the first and last values alphabetically. It's not perfect, because it doesn't guarantee that the value selected is the last one, but it's better than just a load of nulls which is what using Last() might give.

Access seems resistant to the idea of returning the last non-null value in a query using GROUP BY. Even if your FROM clause were modified to be something like
FROM (
SELECT allfieldsyouneed
FROM DuplicateStudents
ORDER BY PlannedStart
) AS SortedDuplicates
and the rest of your query were modified to use SortedDuplicates instead, Access doesn't seem to return the last value based on the order you specify. I tested on a table with exactly one blank row and specific orders that I could verify (both an auto-increment field and a value that I checked by using Min and Max), and Access chose to return some other value as Last.

Based on your comment it seems like your definition of "Last" is: the most recently added record, based on an auto-incrementing ID. As such, some form of the following should work (it uses a subquery to return the most recent non-null UcasNumber):
SELECT Min(Duplicates.AttendedODBefore) AS AttendedODBefore,
Min(Duplicates.ContactByPost) As ContactByPost,
Last(Duplicates.PlannedStart) As PlannedStart,
Min(Duplicates.AccessibilityRequirements) AS AccessibilityRequirements,
(SELECT TOP 1 D.UcasNumber FROM Duplicates AS D
WHERE D.UcasNumber Is Not Null
ORDER BY D.ID DESC) As UcasNumber
FROM DuplicateStudents As Duplicates

Related

Getting another column from same row which has first non-null value in column

I have a SQL table like this and I want to find the average adjusted amt for products partitioned by store_id that looks like this
Here, I need to compute the adj_amt which is the product of the previous two columns.
For this, I need to fill the nulls in the avg_quantity with the first non_null value in the partition. The query I use is below.
select
CASE WHEN av_quantity is null then
# the boolen here is for non-null values
first_value(av_quantity, True) over (partition by store_no order by product_id
range between current row and unbounded following
)
else av_quantity
end as adj_av_quantity
I'm having trouble with the SQL required to get the adjusted cost, since its not pulling the first non_null value for factor but still fetches it based on the same row for the adj_av_quantity. any thoughts on how I could do this?
FYI I've simplified the data here. The actual dataset is pretty huge (> 125 million rows with 800+ columns) so I won't be able to use joins and have to do this via window functions. I'm using spark-sql

SQL Query getting not results

I have a Select statement that gets the items based on the greatest date. it works but these are selected value from asp.net controls and one of the controls is a multiselect listbox
as you can see DynamicAtrributeID 937766 is show one time:
I need it to show all the rows that were in 937766 as well as the other rows which could be just one row. Is this possible
SELECT VotingValueDynamicId,
DecisionValueID,
DynamicAttributeID,
VotingValue,
DecisionSurveyID,
VALUEDATEUPDATED,
RECORDSTATUS,
FROM Adjudicate.ONCOLOGY_DynamicDecisionValuesForCaseManager AS a
WHERE (VALUEDATEUPDATED =
(SELECT MAX(VALUEDATEUPDATED) AS Expr1
FROM Adjudicate.ONCOLOGY_DynamicDecisionValuesForCaseManager AS b
WHERE (a.DecisionValueID = DecisionValueID) AND a.DynamicAttributeID = DynamicAttributeID) ) AND (RECORDSTATUS <> 'D')
In the example shown, all the rows with DynamicAtrributeID = 937766 have different values on VALUEDATEUPDATED, so the query is showing one row for that DynamicAtrributeID because that's what you're doing, filtering and getting only the row wich has the max VALUEDATEUPDATED.
In other words, you can't get more than one row for a DynamicAtrributeID if you're filtering by his max(VALUEDATEUPDATED).
As #necoflecap1 said , the issue is your filter condition, For VALUEDATEUPDATED , you are filtering max(VALUEDATEUPDATED) which any way going to give 1 value per DynamicAttributeID and DecisionValueID combination,since your filter in subquery is
WHERE (a.DecisionValueID = DecisionValueID) AND (a.DynamicAttributeID =
DynamicAttributeID)
I can see two possibilities here , either add one more filter for VotingValue column
WHERE (a.DecisionValueID = DecisionValueID) AND (a.DynamicAttributeID =
DynamicAttributeID) and (a.VotingValue=b.VotingValue)
or Do a
group By VotingValue
inside filter subquery for max(VALUEDATEUPDATED) so that aggregation will perform for every VotingValue (which is the column I can see coming with a different value for DynamicAtrributeID 937766)

Access VBA: Get difference in value between current and previous record

I have made report based on query according to this link:
http://www.techonthenet.com/access/queries/max_query2.php
It gives me list of records with values:
(primaryKey)
ID.......FirstNum....SecNum.....Diameter.....Owner
1........100200.......01...............150..............Peter
2........100200.......02...............138..............Peter
3........100300.......07...............112..............John
Query sorts records in descending order by Diametral. I want make new column which will count difference between first and second record, then between third and second and so on. Like this:
(primaryKey)
ID.......FirstNum....SecNum.....Diameter.....DiffDiametral.....Owner
1........100200.......01...............150.......................................Peter
2........100200.......02...............138.............12......................Peter
3........100300.......07...............112.............26.....................John
What should I write into RowSource or DataSource for DiffDiametral to get these values? How can I avoid error for first line, where is not previous value which I want substract from?
I tried to solve it according to this link:
http://support.microsoft.com/kb/101081/en-us
but I did not solve it. Simply I dont know how I can refer previous value of Diameter to count difference.
Based on your information, a subquery should do it. Just substitute your actual table name for tblDiameters.
SELECT C.ID, C.FirstNum, C.SecNum, C.Diameter, C.Owner,
(SELECT TOP 1 P.Diameter
FROM tblDiameters AS P
WHERE P.Diameter < C.Diameter
ORDER BY P.Diameter DESC )
- C.Diameter AS DiffDiameter
FROM tblDiameters AS C

How to get MAX Values using the Having Clause in MS Access

I have a Column(Fields) that contain multiple values for each entity (One to Many).
Example: A record can can reference multiple values in this column.
What I want to do is get only records where highest(MAX) value in this column is equals zero.
The first thing I did was convert the values in the column to Integer, this way I can get the Max Value.
Here is my Code:
How do I get the Max code? If a record has more than one code. I want only record with the Max or highest code of 00000.
I am getting an error with the Having clause since I cannot use Aggregate in the Where Clause.
SELECT CUSTOMER.USER_ID, MAX(CInt(CUSTOMER.REC_CODE)) AS ACTIVE_REC_CODE,
CUSTOMER.CUS_TYPE
FROM CUSTOMER
WHERE ((CUSTOMER.REC_CODE) IS NOT NULL )
GROUP BY
CUSTOMER.USER_ID, CUSTOMER.REC_CODE, CUSTOMER.CUS_TYPE
HAVING MAX(CInt([CUSTOMER.REC_CODE])= 00000 )
You are close, but you need to remove CUSTOMER.REC_CODE from your WHERE, since you want the max value of that column. This should work:
SELECT CUSTOMER.USER_ID, MAX(CInt(CUSTOMER.REC_CODE)) AS ACTIVE_REC_CODE, CUSTOMER.CUS_TYPE
FROM CUSTOMER
WHERE CUSTOMER.REC_CODE IS NOT NULL
GROUP BY CUSTOMER.USER_ID, CUSTOMER.CUS_TYPE
HAVING MAX(CInt([CUSTOMER.REC_CODE])) = 0

Oracle Group by issue

I have the below query. The problem is the last column productdesc is returning two records and the query fails because of distinct. Now i need to add one more column in where clause of the select query so that it returns one record. The issue is that the column i need
to add should not be a part of group by clause.
SELECT product_billing_id,
billing_ele,
SUM(round(summary_net_amt_excl_gst/100)) gross,
(SELECT DISTINCT description
FROM RES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele) productdescr
FROM bil.bill_sum aa
WHERE file_id = 38613 --1=1
AND line_type = 'D'
AND (product_billing_id, billing_ele) IN (SELECT DISTINCT
product_billing_id,
billing_ele
FROM bil.bill_l2 )
AND trans_type_desc <> 'Change'
GROUP BY product_billing_id, billing_ele
I want to modify the select statement to the below way by adding a new filter to the where clause so that it returns one record .
(SELECT DISTINCT description
FROM RRES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele
AND (rate_structure_start_date <= TO_DATE(aa.p_effective_date,'yyyymmdd')
AND rate_structure_end_date > TO_DATE(aa.p_effective_date,'yyyymmdd'))
) productdescr
The aa.p_effective_date should not be a part of GROUP BY clause. How can I do it? Oracle is the Database.
So there are multiple RES.tariff records for a given product_billing_id/billing_ele, differentiated by the start/end dates
You want the description for the record that encompasses the 'p_effective_date' from bil.bill_sum. The kicker is that you can't (or don't want to) include that in the group by. That suggests you've got multiple rows in bil.bill_sum with different effective dates.
The issue is what do you want to happen if you are summarising up those multiple rows with different dates. Which of those dates do you want to use as the one to get the description.
If it doesn't matter, simply use MIN(aa.p_effective_date), or MAX.
Have you looked into the Oracle analytical functions. This is good link Analytical Functions by Example