Unibasic/ Unidata query - sql

How can we select the most recent record for the unidata queries.
Is there any function or command we can use?
I have data as
Student Term Program Term_Start_date
1, 2018Fall , ABC, 08/01/2018
1, 2018Spring, MATH, 01/01/2018
1, 2017Fall, HIST, 08/01/2017
2, 2017Fall, ENG, 08/01/2017
2, 2017Summer, MATH, 05/01/2017
I want to see the out put as this- Most recent term start date should show per student.
Student Term Program Term_Start_date
1, 2018Fall , ABC, 08/01/2018
2, 2017Fall, ENG, 08/01/2017
I have used the BY.DSND SAMPLE 1 but it gets only one record

Well outside of writing a UniBasic program to parse the data, you can use an "I or V" type VOC entry to call in concert with the LIST query. Something like this.
DISCLAIMER: Don't make entries or delete entries in your UniData database if you're not comfortable or experienced in UniData. There is NOT an "Undo" button.
Don't enter the quoted text. This is just to highlight what is going on.
AE VOC TEST "TEST or any name that isn't in use"
I "For Insert"
I "I Type entry"
DCOUNT(TERM,#VM); EXTRACT(#RECORD,3,#,0)
PRESS Enter
FI
At this point you have a virtual VOC entry that you can call as a condition to your "LIST" query. Like this.
LIST STUDENT TERM PROGRAM DATE WHEN DATE = TEST
This will return the last multivalued record for the TERM attribute per student. This is assuming that TERM is multivalued and that STUDENT is a singlevalued attribute. How this works is that it's counting the value marks and then returning the record and associated attributes based on the count.
The file has to be set up with single/multivalued combination for the DCOUNT function to be able to count per singlevalued attribute. In this instance a STUDENT can have many TERM's with each TERM having it's own date. Now this isn't a logical sort, it's not ranking dates based on a calendar, but rather based on the order they appear in the file.
01-01-18
05-01-17
01-01-09 <-- Date Returned
--- First Answer ---
If you're using Uniquery:
LIST CUSTMST ALL BY.DSND #ID SAMPLE 1
Which will sort the file by a value and then just select 1 record.

Related

Retrieving Columns with count greater than 1 - Google Sheet Query

I'm using Google sheets, and I want to get the data from one sheet to another where I want only the columns with count > 1.
Let's say we have 3 columns A, B, and C. I tried the following (the first sheet name is "Form Responses 1"):
I thought about using a query in the second sheet as: =query('Form Responses 1'!A1:Z, "Select A having count (A) >1 union select B having count (B) >1 union select C having count (C) > 1"). But I got a parse error where it seems that union and having are not supported in google sheets query.
How can I achieve this (whether it's using query or any other Google sheets function that can work)?
More details:
The first sheet contains info about exercises conducted during a lecture and it gets its data from a Google Form (so the responses are fed in this sheet). Here is a screenshot of it:
Please note that the form is divided into sections. When the user selects the course, the attendance, the participation, and adds a comment, then they go to the next section, the next section will be based on the selected course, the newly opened section will have the exercise name and rating questions (the exercise name is a dropdown list with items that are prefilled and specific to the selected course). That's why, you can see that "exercise name" and "rate the exercise" columns are repeated because we have 2 sections in this form.
The second sheet should contain the data of a selected course only (either mobile dev or web dev) which can be achieved easily through a query with a where clause. But, in addition to that, it shouldn't contain the empty columns of "exercise name" and "rate the exercise" as they correspond to another section. So, it should have only one exercise name column and one rating column that correspond to the selected course. Here is a screenshot if we only use a query with where clause without removing the extra name and rating columns:
Here is a screenshot with the desired result:
Thanks.
why not use just:
=QUERY('Form Responses 1'!A1:Z, "select A,B,C,D,E,F,G where F is not null", 1)
Use "OR" condition
Eg:-
QUERY(Data!A:R,"select A, N, P where N>0 or P>0")
where A column has country and N, P columns have population values

Google Sheets Query WHERE clause just returns first row of data

I have a sheet which I am trying to use to show an overview of students results in a number of subjects, with each student and their results in separate rows.
OVERVIEW
studentID, English, Maths, etc
1, result1, result2, etc
2, result3, result4, etc
The result data comes from another system and is in a separate sheet. Each result for each subject is a separate row where the first column is the student ID, the second is the subject and the third is the result.
RESULTSET
1, ENGLISH, result 1
1, MATHS, result 2
etc.
I've been trying various forms of a query like this
=query(RESULTSET!A1:C,"SELECT C WHERE A = '1' AND B = 'ENGLISH'",1) but the query only ever returns the first result from the first row of data in RESULTSET.
Here is a link to a test spreadsheet containing data and queries that reproduces the issue: https://docs.google.com/spreadsheets/d/15xLAyHumL2pC8mRfA4Qs9xMyrWZvK86kmoi2kBWnB34/edit?usp=sharing
I am expecting to see results from the result set that matches each student ID and subject, but I am only ever seeing the first result irrespective of ID or subject.
Remove the single quotes around the reference to column A and set the headers argument in query() to zero. In B2 try
=iferror(query('result set 1'!$A$1:$C58,"SELECT C WHERE A = "&$A2&" AND B = '"&UPPER(B$1)&"'",0))
Fill down to the right and down as far as needed and see if that works?
Another option would be to use in B2
=ArrayFormula(iferror(vlookup($A$2:$A$8&B$1, {'result set 1'!$A:$A&'result set 1'!$B:$B, 'result set 1'!$C:$C}, 2, 0)))
and fill to the right (make sure there is no data below row 2).

SAP BO - how to get 1/0 distinct values per week in each row

the problem I am trying to solve is having a SAP Business Objects query calculate a variable for me because calculating it in a large excel file crashes the process.
I am having a bunch of columns with daily/weekly data. I would like to get a "1" for the first instance of Name/Person/Certain Identificator within a single week and "0" for all the rest.
So for example if item "Glass" was sold 5 times in week 4 in this variable/column first sale will get "1" and next 4 sales will get "0". This will allow me to have the number of distinct items being sold in a particular week.
I am aware there are Count and Count distinct functions in Business Objects, however I would prefer to have this 1/0 system for the entire raw table of data because I am using it as a source for a whole dashboard and there are lots of metrics where distinct will be part/slicer for.
The way I doing it previously is with excel formula: =IF(SUMPRODUCT(($A$2:$A5000=$A2)*($G$2:$G5000=$G2))>1,0,1)
This does the trick and gives a "1" for the first instance of value in column G appearing in certain value range in column A ( column A is the week ) and gives "0" when the same value reappears for the same week value in column A. It will give "1" again when the week value change.
Since it is comparing 2 cells in each row for the entire columns of data as the data gets bigger this tends to crash.
I was so far unable to emulate this in Business Objects and I think I exhausted my abilities and googling.
Could anyone share their two cents on this please?
Assuming you have an object in the query that uniquely identifies a row, you can do this in a couple of simple steps.
Let's assume your query contains the following objects:
Sale ID
Name
Person
Sale Date
Week #
Price
etc.
You want to show a 1 for the first occurrence of each Name/Week #.
Step 1: Create a variable with the following definition. Let's call it [FirstOne]
=Min([Sale ID]) In ([Name];[Week #])
Step 2: In the report block, add a column with the following formula:
=If [FirstOne] = [Sale ID] Then 1 Else 0
This should produce a 1 in the row that represents the first occurrence of Name within a Week #. If you then wanted to show a 1 one the first occurrence of Name/Person/Week #, you could just modify the [FirstOne] variable accordingly:
=Min([Sale ID]) In ([Name];[Person];[Week #])
I think you want logic around row_number():
select t.*,
(case when 1 = row_number() over (partition by name, person, week, identifier
order by ??
)
then 1 else 0
end) as new_indicator
from t;
Note the ??. SQL tables represent unordered sets. There is no "first" row in a table or group of rows, unless a column specifies that ordering. The ?? is for such a column (perhaps a date/time column, perhaps an id).
If you only want one row to be marked, you can put anything there, such as order by (select null) or order by week.

Using IF THEN in Access 2010 Query

I'm not very knowledgeable in coding of Access queries, so I hope someone can help with this issue.
I have a query (using the query builder) that has a field named RetrainInterval from table tblProcedures (this will return a number like 1, 3, 6, 12, etc.; the rotational months the particular document have to be retrained on) and another field named Training/Qualification Date from table tblTrainingRecords.
I want the query to look at the RetrainInterval for a given record (record field is ClassID in tblProcedures) and then look at the Training/Qualification Date and calculate if that record should be in the query.
In a module I would do this:
IF RetrainInterval = 1 Then
DateAdd("m",1,[Training/Qualification Date]) <add to query if <=today()+30>
ElseIf RetrainInterval = 3 Then
DateAdd("m",3,[Training/Qualification Date]) <add to query if <=today()+30>
ElseIF......
How can I translate this into something that would work in a query? My end goal is to generate a report that will show me what document class numbers are due within a specified time interval (say I enter 30 in the form textbox to represent any upcoming required training within 30 days of the query), but all of the calculations to determine this is based off of when the last training date was (stored in the training records table). I also want to make sure that I do not get multiple returns for the same class number since there will be multiple training entries for each class, just grab the minimum last training date. I hope I explained it well enough. It's hard to put this into words on what I am trying to do without positing up the entire database.
UPDATE
I think I have simplified this a bit after getting some rest. Here are two images, one is the current query, and one is what comes up in the report. I have been able to refine this a bit, but now my problem is I only want the particular Class to show once on the report, not twice, even though I have multiple retrain due dates (because everything is looking at the table that holds the employee training data and will have multiple training's for each Class number). I would like to only show one date, the oldest. Hope that makes sense.
Query - http://postimg.org/image/cpcn998zx/
Report - http://postimg.org/image/krl5945l9/
When RetrainInterval = 1, you add 1 month to [Training/Qualification Date].
When RetrainInterval = 3, you add 3 months to [Training/Qualification Date].
And so on.
The pattern appears to be that RetrainInterval is the number of months to add. If that is true, use RetrainInterval directly in your DateAdd() expression and don't bother about IF THEN.
DateAdd("m", RetrainInterval, [Training/Qualification Date])
You can not do that in a query. Been there, cursed that!
You can use the IFF( 2>x ; 1 ;0)
Giving that if the first statement is true, 1 is returned, and 0 if false.
You can not return a criteria like IFF(2>x ; Cell>2 ; Cell>0) (Not possible) It will just return 0 if you try, i think. it will not give an error all the time.
You have to use criterias!
I would to something like this picture:
I hope you follow, else let me know.

MS SQL 2000 - How to efficiently walk through a set of previous records and process them in groups. Large table

I'd like to consult one thing. I have table in DB. It has 2 columns and looks like this:
Name...bilance
Jane...+3
Jane...-5
Jane...0
Jane...-8
Jane...-2
Paul...-1
Paul...2
Paul....9
Paul...1
...
I have to walk through this table and if I find record with different "name" (than was on previous row) I process all rows with the previous "name". (If I step on the first Paul row I process all Jane rows)
The processing goes like this:
Now I work only with Jane records and walk through them one by one. On each record I stop and compare it with all previous Jane rows one by one.
The task is to sumarize "bilance" column (in the scope of actual person) if they have different signs
Summary:
I loop through this table in 3 levels paralelly (nested loops)
1st level = search for changes of "name" column
2nd level = if change was found, get all rows with previous "name" and walk through them
3rd level = on each row stop and walk through all previous rows with current "name"
Can this be solved only using CURSOR and FETCHING, or is there some smoother solution?
My real table has 30 000 rows and 1500 people and If I do the logic in PHP, it takes long minutes and than timeouts. So I would like to rewrite it to MS SQL 2000 (no other DB is allowed). Are cursors fast solution or is it better to use something else?
Thank you for your opinions.
UPDATE:
There are lots of questions about my "summarization". Problem is a little bit more difficult than I explained. I simplified it just to describe my algorithm.
Each row of my table contains much more columns. The most important is month. That's why there are more rows for each person. Each is for different month.
"Bilances" are "working overtimes" and "arrear hours" of workers. And I need to sumarize + and - bilances to neutralize them using values from previous months. I want to have as many zeroes as possible. All the table must stay as it is, just bilances must be changed to zeroes.
Example:
Row (Jane -5) will be summarized with row (Jane +3). Instead of 3 I will get 0 and instead of -5 I will get -2. Because I used this -5 to reduce +3.
Next row (Jane 0) won't be affected
Next row (Jane -8) can not be used, because all previous bilances are negative
etc.
You can sum all the values per name using a single SQL statement:
select
name,
sum(bilance) as bilance_sum
from
my_table
group by
name
order by
name
On the face of it, it sounds like this should do what you want:
select Name, sum(bilance)
from table
group by Name
order by Name
If not, you might need to elaborate on how the Names are sorted and what you mean by "summarize".
I'm not sure what you mean by this line... "The task is to sumarize "bilance" column (in the scope of actual person) if they have different signs".
But, it may be possible to use a group by query to get a lot of what you need.
select name, case when bilance < 0 then 'negative' when bilance >= 0 then 'positive', count(*)
from table
group by name, bilance
That might not be perfect syntax for the case statement, but it should get you really close.