Writing a specific SQL query - sql

I have a database which saves data from a survey where one person can take survey one or two times, and not more than that. I have a column DATE through which I want to get all peoples first survey(not second one).
For example, the person with EMAIL shane#gmail.com has given survey on DATE 29th and 30th of December. Same way person with EMAIL mike#gmail.com has given survey on DATE 1st nov and 28th dec.
I want to get both persons first survey records. Thank you

Without the schema it's difficult to guess at what you need. But if it's as simple as a table with email and survey dates it could be something like this:
select email, survey_date
from myTable
group by email
order by survey_date asc

You can cross the table with itself
select * from table t1 join table t2
on t1.email = t2.email
and t1.surveydate < t2.surveydate
PS: you can optimize the query with a clause "WITH", if your database engine supports it. This query will work correctly as long as there only 2 records for each email as you have exposed

Related

Finding if Any date in a table is between 2 dates

I have a SQL query where I need to find out if any date in a table relating to a specific client is between another date in a different table and that date plus 5 days
I have a table with a list of client details (client table) with the fields clients name, address and ID (PK) in it
I have a table with the annual assessments details where we review the clients account (assessment table) with the fields assessment date and assessment ID (pk) in it
I a separate table with a list of the dates we have spoken with the client (meeting table) with the fields Meeting name (eg meeting type 1, meeting type 2, meeting type 3) meeting date, meeting ID (PK)
We can see the clients a lot of times during the year for different meetings, however I need a query that will tell me Yes or No, has the client been spoken to with 5 days of the annual assessment.
So I need something like the below
Select
Client_ID (PK) (from client table)
,Client_Name (from client table)
,Assessment_ID (PK) from assessment table
,Assessment_date (from assessment table)
Then here I need something here that will say, CASE WHEN from all of the dates in the meetings table relating to this client, are any of them within 5 days of the assessment date if so 'Y' if not 'N'
I'm fine with joining all the relevant table as and when required it's just the query for any date in the meeting table between assessment date and assessment date + 5 that I am struggling with.
Any help, greatly appreciated.
Something like this.
SELECT CustomerData
,CASE
WHEN DATEDIFF(DAY, MeetingDate, GETDATE()) < 5 THEN 'Yes'
ELSE 'No'
END AS CustomerConsultedLastFiveDays
FROM CustomerMeetingTable
WHERE Conditions = Conditions;
it's interesting to pay attention to some points:
If the Customers table has a relationship with the evaluation table, if so you can make an inner join between the two, finding what evaluations have for an X customer.
If you already have this relationship now, do an inner join, Exists or IN to validate if Client X exists in the Meeting table.
If it is not possible to make this relationship by PK, it is a problem regarding the structure of the data, since without reference to the customer in the meeting table, I did not find a way to make this relationship in your text.
Assuming you've done everything I mentioned above just make a CASE for your code
for example:
Note: I didn't quite understand the filter point related to the dates of the two tables, so I left the WHERE like this,
Graciously.

Query build to find records where all of a series of records have a value

Let me explain a little bit about what I am trying to do because I dont even know the vocab to use to ask. I have an Access 2016 database that records staff QA data. When a staff member misses a QA we assign a job aid that explains the process and they can optionally send back a worksheet showing they learned about what was missed. If they do all of these ina 3 month period they get a credit on their QA score. So I have a series of records all of whom have a date we assigned the work(RA1) and MAY have a work returned date(RC1).
In the below image "lavalleer" has earned the credit because both of her sheets got returned. "maduncn" Did not earn the credit because he didn't do one.
I want to create a query that returns to me only the people that are like "lavalleer". I tried hitting google and searched here and access.programmers.co.uk but I'm only coming up with instructions to use Not null statements. That wouldn't work for me because if I did a IS Not Null on "maduncn" I would get the 4 records but it would exclude the null.
What I need to do is build a query where I can see staff that have dates in ALL of their RC1 fields. If any of their RC1 fields are blank I dont want them to return.
Consider:
SELECT * FROM tablename WHERE NOT UserLogin IN (SELECT UserLogin FROM tablename WHERE RCI IS NULL);
You could use a not exists clause with a correlated subquery, e.g.
select t.* from YourTable t where not exists
(select 1 from YourTable u where t.userlogin = u.userlogin and u.rc1 is null)
Here, select 1 is used purely for optimisation - we don't care what the query returns, just that it has records (or doesn't have records).
Or, you could use a left join to exclude those users for which there is a null rc1 record, e.g.:
select t.* from YourTable t left join
(select u.userlogin from YourTable u where u.rc1 is null) v on t.userlogin = v.userlogin
where v.userlogin is null
In all of the above, change all occurrences of YourTable to the name of your table.

SQL - select IDs that have been seen in table w/ timestamp <= 1+ year

I have a table with user IDs, timestamps, and sales info. The same user IDs appear multiple times in the data (every time they purchase). I only want to select the user IDs that have shown up in the table for at least a year (so, for the sake of simplicity I'll do a timestamp less than "12-31-2016"). How can I write this with SQL?
Try this:
Select Distinct userID
FROM Table
WHERE DATEDIFF(yy,cast(Timestamp as date),getdate())>=1
Updated based on your comment:
Select Distinct userID
FROM Table
WHERE CAST(Timestamp as date)>'20161231'

mysql join question, joining newest record in a one to many relationship

I have a simple (hopefully) SQL question for you, any help would be much, much appreciated :).
I have two tables which I would like to join.
One Is Users, lets say it's called users
One is a kind of history of that user, lets say its called users_history.
The relationship of these two is a one users to many users_history relationship.
What I'd like to do is a query which joins the tables and joins the newest record in users_history onto each user.
Lets say the tables are like this, I'm simplifying for conciseness.
users
id
name
users_history
id
user_id
date
The date is formatted YYYYMMDD.
The end result is I'd like to be able to pull out all of the users who don't have a users_history record for today, for example today is 20101021.
Any help would be very gratefully received! :)
Try
SELECT MAX(users_history.date), users.name FROM users
LEFT JOIN users_history ON users.id = users_history.user_id
GROUP BY users_history.user_id
HAVING MAX(users_history.date) < CURDATE()
If you dont want users who doesnt have eny users_history records in the resultset, change the "LEFT JOIN" to a "JOIN"
If all you really want is finding the users without a user_history entry for today, you can use a subquery like so:
SELECT * FROM users WHERE NOT EXISTS (SELECT id FROM users_history WHERE user_id = users.id AND `date` = DATE(NOW()));
IMHO, this is more readable than a join and some filtering in your host language.
edit: Judging from your date format description, you probably use a varcharcolumn to store the date. In that case, replace DATE(NOW()) with the appropriate string representation for "today" - though I'd recommend changing the column type to a date/time type.
pull out all of the users who don't have a users_history record for today, for example today is 20101021.
select
u.*
from
users u
left outer join users_history uh on
u.id = uh.user_id and uh.history_date = curdate()
where
uh.user_id is null;

SQL Distinct Query

My SQL seems to be letting me down this morning. I have a table with the columns
Id, Guid,AttributeId,AttributeValue,CreationDate,Status
This stores data from a qustonnaire which has around 15 pages to it. Each time you move on to the next question (next page) in the questionnaire the entire questionnaire is persisted to the table i.e after completing the 1st question, that questions data is stored in the table, after completing the 2nd question, the 1st and 2nd question is persisted to the table meaning that know, we have two lots of the 1st qestion and one lot of the second question saved in the table.
I need to write a query that will return the latest lot of saved data for a given questionnaire (and all questionnaires). i.e. if the user got to question 13 i would want only that set of data returned.
Something like...
SELECT Q.*
FROM Questionnaire Q
INNER JOIN (
SELECT TOP 1 Guid, CreationDate
FROM Questionnaire
ORDER BY CreationDate DESC
) Q2
ON Q2.Guid = Q.Guid AND Q2.CreationDate = Q.CreationDate
...ought to do it. The join to Guid is possibly redundant - and you'll presumably need a WHERE somewhere to ensure you get the questionnaire for the particular user / session.
Maybe this does the trick...
SELECT TOP 1 * FROM Questionaire ORDER BY CreationDate DESC