Access 2010 conditional selection in query - sql

I'm trying to complete my university coursework but i'm stuck with the selection process in a query.
Running Access 2010, I have to select the following fields:
Asset ID, Asset Description, Problem ID, Current Helpdesk person allocated to the problem or the date solved and the solution given.
How can I do a conditional select so that basically like it says, IF solution date is filled in, fetch the date and description. Otherwize, fetch the Helpdesk person who is assigned.
Please assume that all fields are in the Problems table and I can adapt from there as needed, just need a heads up on how to select a column in one case and if the case resolves to false, select an alternative column.

I have not much idea about MS Access, but you can try it with IIF() function like below as MS Access doesn't support CASE WHEN clause. You can also use Format() function to convert date in string with whatever format you want.
SELECT Asset_ID,
Asset_Description,
Problem_ID
IIF(IsNull(Date), Helpdesk_Person, CStr(Date) + Description) as Solution
FROM Problems

Related

MS Access subquery from identical table

I am currently working on an access database where we collect customers feedback.
I have one table with the following structure and data :
And I want to display the following result :
Indeed, what I want is a MS Access Request that displays, for every date value in my table, the amount of records that matches the same date on the column "date_import" (2nd column of the result) and the amount of records that matches this criteria on the column "date_answered" (3rd column of the result).
I have no idea how to do this since all the subqueries should be aware of each other.
Has anyone ever faced this issue and might be able to help me ?
Thanks in advance,
P.S. : I'm using the 2016 version of MS Access but I'm pretty sure what I'm trying to do is also achievable in previous versions of Access, this is what I added several tags.
Hmmm . . . I think this will work:
select dte, sum(is_contact), sum(is_answer)
from (select date_import as dte, 1 as is_contact, 0 as is_answer
from t
union all
select date_answers, 0 as is_contact, 1 as is_answer
from t
) t
group by dte;
Not all versions of MS Access allow union all in the FROM clause. If that is a problem, you can create a view and then select from the view.

How to select all data from table but only display date-specific rows within DATE-data type column, in Oracle SQL?

I'm experiencing trouble returning a query to return all columns within a table but limited to the DATE-data-type "enroll_date" column containing '30-Jan-07'; the closest solution is with the below query but neither data is displayed nor the entire workbook-just the column-which leads me to believe that this is not just an issue with approach but perhaps a formatting issue as well.
SELECT TO_DATE(enroll_date, 'DD-MM-YY')
FROM student.enrollment
WHERE enroll_date= '30-Jan-07';
Again, I need to display all columns but only rows only specific to the date '30-Jan-07'. I'm sure a nested solution is ideal and somehow the right solution, but unfortunately my chops aren't there yet but I'm working on it! :D
UPDATE
Please see attached screenshot of output. The query/solution should retrieve all columns and rows enclosed within the red-rectangle mark-up-thank you!
One possible problem is that the date column has a time component (this is hidden in SQL). One method is to use trunc():
SELECT e.*
FROM student.enrollment e
WHERE TRUNC(e.enroll_date) = DATE '2007-01-30';
You can specify whichever columns you want in the following query:
SELECT col1, col2, col3, ...
FROM student.enrollment
WHERE TO_CHAR(enroll_date, 'DD-MON-YY') = '30-JAN-07';

Access - SQL Query -> find most recent record and save it to a table

I am sure this has been asked before and I have found several references to similar things. I just can't work out how to make it work for me.
I have a table (tblHistory) with data
Unit Number,Action,LoggerID,SensorID,CableID,Date,Data Location etc
I also have another table (tblUnit) with more data
Unit,Logger,Sensor,Cable
I want to create a query that scours tblHistory to find the most recent LoggerID, SensorID and CableID for each Unit.
To add to this there may need to be safeguards in the query in case the user does not place Logger, Sensor or Cable IDs so that it does not just find the most recent date and return a null value.
The final aspect of this which may or may not be simple is that I want this to overwrite the data in the tblUnit table so that when a new logger, sensor or cable is in place the unit uses this new data. I don't want these fields to be just edited because I want to keep a history of it. My knowledge of SQL and Access is pretty limited as I'm usually more familiar with excel and vb.
I have tried using these:
MSAccess: select N records from each category
sql for finding most recent record in a group
but being a beginner I'm not 100% sure how to apply them to my problem.
If anyone can help that would be great.
Example: (tblHistory)
Unit Number,Action,LoggerID,SensorID,CableID,ActionDate
1,Replace Sensor,,KTSM01S03,,15/02/2015
1,Replace Logger,KTSM01FM02,,,11/01/2014
1,Replace Cable,,,sa123124,10/01/2014
1,Replace Logger,KTSM01FM03,,,12/01/2014
2,Replace Sensor,,KTSM01S01,,13/01/2014
2,Replace Cable,,,sa123123,12/01/2014
2,Replace Cable,,,sa123124,16/02/2014
2,Replace Logger,KTSM01FM01,,,13/01/2014
tblUnit
Unit Number,Logger,SensorID,Cable
1,KTSM01FM01,KTSM01S01,sa123123
2,Logger1,Sensor1,Cable1
SELECT TOP 1 *
FROM tblHistory a
INNER JOIN
(SELECT Unit Number, Max([Date]) as MaxDate
FROM tblHistory
GROUP BY Unit Number) b
on a.[Unit Number] = b.[Unit Number]
and a.[Date] = b.MaxDate
You have to bracket the field called Date because Date() is a reserved function and Access will think you're trying to use the function instead of calling the field in your table. In the future, always try to avoid using reserved words as field names, it will save you a lot of headaches.

SQL statement HAVING MAX(some+thing)=some+thing

I'm having trouble with Microsoft Access 2003, it's complaining about this statement:
select cardnr
from change
where year(date)<2009
group by cardnr
having max(time+date) = (time+date) and cardto='VIP'
What I want to do is, for every distinct cardnr in the table change, to find the row with the latest (time+date) that is before year 2009, and then just select the rows with cardto='VIP'.
This validator says it's OK, Access says it's not OK.
This is the message I get: "you tried to execute a query that does not include the specified expression 'max(time+date)=time+date and cardto='VIP' and cardnr=' as part of an aggregate function."
Could someone please explain what I'm doing wrong and the right way to do it? Thanks
Note: The field and table names are translated and do not collide with any reserved words, I have no trouble with the names.
Try to think of it like this - HAVING is applied after the aggregation is done.
Therefore it can not compare to unaggregated expressions (neither for time+date, nor for cardto).
However, to get the last (principle is the same for getting rows related to other aggregated functions as weel) time and date you can do something like:
SELECT cardnr
FROM change main
WHERE time+date IN (SELECT MAX(time+date)
FROM change sub
WHERE sub.cardnr = main.cardnr AND
year(date)<2009
AND cardto='VIP')
(assuming that date part on your time field is the same for all the records; having two fields for date/time is not in your best interest and also using reserved words for field names can backfire in certain cases)
It works because the subquery is filtered only on the records that you are interested in from the outer query.
Applying the same year(date)<200 and cardto='VIP' to the outer query can improve performance further.

SQL Group By

If I have a set of records
name amount Code
Dave 2 1234
Dave 3 1234
Daves 4 1234
I want this to group based on Code & Name, but the last Row has a typo in the name, so this wont group.
What would be the best way to group these as:
Dave/Daves 9 1234
As a general rule if the data is wrong you should fix the data.
However if you want to do the report anyway you could come up with another criteria to group on, for example LEFT(Name, 4) would perform a grouping on the first 4 characters of the name.
You may also want to consider the CASE statement as a method (CASE WHEN name = 'Daves' THEN 'Dave' ELSE name), but I really don't like this method, especially if you are proposing to use this for anything else then a one-off report.
If it's a workaround, try
SELECT cname, SUM(amount)
FROM (
SELECT CASE WHEN NAME = 'Daves' THEN 'Dave' ELSE name END AS cname, amount
FROM mytable
)
GROUP BY cname
This if course will handle only this exact case.
For MySQL:
select
group_concat(distinct name separator '/'),
sum(amount),
code
from
T
group by
code
For MSSQL 2005+ group_concat() can be implemented as .NET custom aggregate.
Fix the typo? Otherwise grouping on the name is going to create a new group.
Fixing your data should be your highest priority instead of trying to devise ways to "work around" it.
It should also be noted that if you have this single typo in your data, it is likely that you have (or will have at some point in the future) even more screwy data that will not cleanly fit into your code, which will force you to invent more and more "work arounds" to deal with it, when you should be focusing on the cleanliness of your data.
If the name field is suppose to be a key then the assumption has to be that Dave and Daves are two different items all together, and thus should be grouped differently. If however it is a typo, then as other have suggested, fix the data.
Grouping on a freeform entered text field if that is what this is, will always have issues. Data entry is never 100%.
To me it makes more sense to group on the code alone if that is the key field and leave name out of the grouping all together.