This should be fairly simple but I am going round the houses !
Using VBA how can I change the criteria of a numerical field in a query with multiple options.
e.g. if I was editing the query I would just type in "1 or 2 or 3"
The Criteria changes at different times of the day, so sometimes it may be "3 or 4" e.t.c.
I am using Office 365.
Any help would be appreciated.....
Use the IN operator and rebuild your SQL when the filter changes:
Select * From YourTable Where ID In (1,2,3)
Select * From YourTable Where ID In (3,4)
Related
Sales :
Q1) Return the name of the agent who had the highest increase in sales compared to the previous year
A) Initially I wrote the following query
Select name, (sales_2018-sales_2017) as increase
from sales
where increase= (select max(sales_2018-sales_2017)
from sales)
I got an error saying I cannot use increase with the keyword where because "increase" is not a column but an alias
So I changed the query to the following :
Select name, (sales_2018-sales_2017) as increase
from sales
where (sales_2018-sales_2017)= (select max(sales_2018-sales_2017)
from sales)
This query did work, but I feel there should be a better to write this queryi.e instead of writing where (sales_2018-sales_2017)= (select max(sales_2018-sales_2017) from sales). So I was wondering if there is a work around to using alias with where.
Q2) suppose the table is as following, and we are asked to return the EmpId, name who got rating A for consecutive 3 years :
I wrote the following query its working :
select id,name
from ratings
where rating_2017='A' and rating_2018='A' and rating_2019='A'
Chaining 3 columns (ratings_2017,rating_2018,rating_2019) with AND is easy, I want know if there is a better way to chain columns with AND when say we want to find a employee who has rating 'A' fro 10 consective years.
Q3) Last but not the least, I'm really interested in learning to write intermediate-complex SQL queries and take my sql skills to next level. Is there a website out there that can help me in this regard ?
1) You are referencing an expression with a table column value, and therefore you would need to define the expression first(either using an inline view/cte for increase). After that you can refer it in the query
Eg:
select *
from ( select name, (sales_2018-sales_2017) as increase
from sales
)x
where x.increase= (select max(sales_2018-sales_2017)
from sales)
Another option would be to use analytical functions for getting your desired results, if you are in mysql 8.0
select *
from ( select name
,(sales_2018-sales_2017) as increase
,max(sales_2018-sales_2017) over(partition by (select null)) as max_increase
from sales
)x
where x.increase=x.max_increase
Q2) There are alternative ways to write this. But the basic issue is with the table design where you are storing each rating year as a new column. Had it been a row it would have been more easy.
Here is another way
select id,name
from ratings
where length(concat(rating_2017,rating_2018,rating_2019))-
length(replace(concat(rating_2017,rating_2018,rating_2019)),'A','')=3
Q3) Check out some example of problems from hackerrank or https://msbiskills.com/tsql-puzzles-asked-in-interview-over-the-years/. You can also search for the questions and answers from stackoverflow to get solutions to tough problems people faced
Q1 : you can simply order and limit the query results (hence no subquery is necessary) ; also, column aliases are allowed in the ORDER BY clause
SELECT
name,
sales_2018-sales_2017 as increase
FROM sales
ORDER BY increase DESC
LIMIT 1
Q2 : your query is fine ; other options exists, but they will not make it faster or easier to maintain.
Finally, please note that your best option overall would be to modify your database layout : you want to have yearly data in rows, not in columns ; there should be only one column to store the year instead of several. That would make your queries simpler to write and to maintain (and you wouldn’t need to create a new column every new year...)
Thank all of you for your help. My Access database is coming along nicely.
My new question is:
I have three fields that are to be considered to get the result I am looking for.
Date, EMPID and the RESULTS field.
The date is simply a date with no time.
The EMPID is a unique employee identifier.
The Results field states either pass or fail.
What I am trying to do is on any single date (there may be many dates, but each is to be considered separately) an employee may test many times and have multiple failures (there can only ever be one passing result). If on the same date the same employee passes, then all fails are to be removed. If there is no pass, then leave one fail.
Thank You,
Query 1: QueryPass
SELECT *
FROM Table1
WHERE Results="Pass";
Query 2: QueryFail
SELECT *
FROM Table1
WHERE EmpID & ResDate Not In (SELECT EmpID & ResDate FROM QueryPass);
Query 3: QueryReport
SELECT EmpID, ResDate, Results FROM QueryFail
UNION SELECT EmpID, ResDate, Results FROM QueryPass;
NOTE: Date is a reserved word in Access, should avoid using reserved words as names for anything.
Since there can be multiple rows per person (and all in the same table), and if someone passes, it will be the 'last' record for that person, the following will give you what you need.
SELECT Last(Table1.[TestDate]) AS LastOfTestDate,
Table1.[EMPID], Last(Table1.[TestResult]) AS LastOfTestResult
FROM Table1
GROUP BY Table1.[EMPID];
I have 2 indentical tables called LIVE and BACKUP.
What I cam trying to do is to compare a LIVE record with its equivalent BACKUP record to see if they match. This check is required each time an individual LIVE record is accessed.
i.e. I only want to compare record number 59 (as an example) rather than all records in the LIVE table?
Currently I can do what I want by simply comparing the LIVE record and its equivalent BACKUP record on a field by field basis.
However, I was wondering if it is possible to do a simple "Compare LIVE record A with BACKUP record A".
I don't need to know what the differences are or even in which fields they occur. I only need to know a simple yes/no as to whether both records match or not.
Is such a thing possible or am I stuck comparing the tables on a field by field basis?
Many thanks,
Pete
Here is a hack, assuming the columns really are all the same:
select count(*)
from ((select *
from live
where record = 'A'
) union
(select *
from backup
where record = 'A'
)
) t
This will return "1" if they are identical and "2" if more than one record exists. If you want to ensure against two values being in the same table, then use the modified form:
select count(distinct which)
from ((select 'live' as which, l.*
from live .
where record = 'A'
) union
(select 'backup' as which, b.*
from backup b
where record = 'A'
)
) t;
Also . . . Note the use of union. The duplicate removal is very intentional here.
I have multiple select statements from different tables on the same database. I was using multiple, separate queries then loading to my array and sorting (again, after ordering in query).
I would like to combine into one statement to speed up results and make it easier to "load more" (see bottom).
Each query uses SELECT, LEFT JOIN, WHERE and ORDER BY commands which are not the same for each table.
I may not need order by in each statement, but I want the end result, ultimately, to be ordered by a field representing a time (not necessarily the same field name across all tables).
I would want to limit total query results to a number, in my case 100.
I then use a loop through results and for each row I test if OBJECTNAME_ID (ie; comment_id, event_id, upload_id) isset then LOAD_WHATEVER_OBJECT which takes the row and pushes data into an array.
I won't have to sort the array afterwards because it was loaded in order via mysql.
Later in the app, I will "load more" by skipping the first 100, 200 or whatever page*100 is and limit by 100 again with the same query.
The end result from the database would pref look like "this":
RESULT - selected fields from a table - field to sort on is greatest
RESULT - selected fields from a possibly different table - field to sort on is next greatest
RESULT - selected fields from a possibly different table table - field to sort on is third greatest
etc, etc
I see a lot of simpler combined statements, but nothing quite like this.
Any help would be GREATLY appreciated.
easiest way might be a UNION here ( http://dev.mysql.com/doc/refman/5.0/en/union.html ):
(SELECT a,b,c FROM t1)
UNION
(SELECT d AS a, e AS b, f AS c FROM t2)
ORDER BY a DESC
I am trying to build an access report based on data from multiple different tables within the database.
I have 3 columns which perform calculations, and I am wondering how to put this query together. All 3 columns deal with dates, but calculate them differently.
The first column retrieves the most recent date of action for a userid if the type of action is "B":
select pid, Max(date) as most_recent
from actions
where ref = 'B'
group by pid;
The second column performs a calculation based on 2 fields, one is a date and one is a number in months. I am unsure how to add these two fields so that the number is added to the date as a number of months.
what i have so far is:
select nummonths,Max(lastvisit) from users
the third column I need to select the first date thats in the future for each user (next appointment date), there will be dates before and after this date so its a little difficult:
select uid,date from visits
The code for the last 2 queries needs to be slightly modified, and I was wondering what the best approach would be to join these all together? A type of join?
If you need to build a report with data from the 3 queries, you will need related data to join them. In that case, please send the structure of the tables.
If you need to show 3 lists in one report, you can use subreports: create a new empty report. In design mode, you can add 3 subreports from the toolbox bar. To each of the subreport assign the record source property to the corresponding sql.
regards
I am unsure how to add these two fields so that the number is added to the date as a number of months.
Use the DateAdd() function:
SELECT DateAdd("m", 2, LastVisit) FROM ...
Results in a date two months from the LastVisit date.