how to limit result based on the fields - database

How to use ' LIMIT' in mysql database query based on fields . just consider a user has 10 phone number and i would like to get only 5 phone number for that user .
I would like to get only 5 phone numbers per user . not only 5 results from database ?

Hmmm... this should be the same (regarding your last sentence):
SELECT phone_number FROM phone_numbers WHERE user_id = XX LIMIT 5
But if you're looking for a sub-select within another query, then you will have to use a JOIN and can't LIMIT this JOIN. So the way to go would be to first select the users and then - on a per-user-basis - select 5 phone numbers for every user.

You can use "ROW_NUMBER() OVER PARTITION (..)" Mysql simulation for the situation Augenfeind described ( if you make a join and select no more than 5 phone numbers for each user ).
See here to understand the logic: http://www.xaprb.com/blog/2005/09/27/simulating-the-sql-row_number-function/
This would be something like:
SELECT * FROM
users u JOIN
(
select l.user_id, l.phone, count(*) as num
from phones as l
left outer join phones as r
on l.user_id = r.user_id
and l.phone >= r.phone
group by l.user_id, l.phone
) p
ON u.user_id=p.user_id AND p.num<=5
Hope that helps.

Related

SQL query to a database

I have an exercice that I've been trying to complete for hours, but still no luck.
Question:
List the name, address e number of borrowed book's for all the clients that have more than 5 books loaned.
The schematic is on the picture below and so far I have done this query, that is missing the number of books loaned
select
Name, Address
from
borrower
where
cardno in (select cardno
from book_loans
group by cardno
having count(cardno) in (select emprestimo.emprestimo
from
(select COUNT(cardno) as emprestimo
from book_loans
group by cardno
having COUNT(cardno) >= 5) emprestimo));
Since you are learning, I'll give you pseudocode. You know about the having clause - that forms the basis for finding the clients. You apply that set of IDs (CardNo) by joining to borrower. Something like:
select <columns>
from (query to find cardnos > 5 books>) as cards
inner join Borrower as brw on ...
order by ...;
And learn the next lesson well - a resultset is not guaranteed to be ordered without an order by clause.

Selecting Different rows if the values of one column are equal

I am trying to write a SQL query that selects the top 4 from a random query so I can do quality checks on the certain cases. Each case has an account number tied to a client. The problem is that each case has a unique number but may have the same account number.
What I am looking to do is if the account number is the same on two cases to have the SQL select a new row with a different account number.
Select Top 4
Account,
CaseNum
From dbo.tblRequest
Where LoggedDate Between GetDate() - 7 and GetDate() - 1
Order By NewId();
The Results will display 4 accounts but at times it is possible that the same account is displayed twice. As stated I want to only display distinct accounts for a 7 day period.
I have tried the distinct key word and it still displays the accounts twice in some queries results.
Try following statement. using row_number to get only on line for same accountNumber.
SELECT * FROM (
Select
Account,
CaseNum,
ROW_NUMBER()OVER(PARTITION BY Account ORDER BY GETDATE()) AS rn
From dbo.tblRequest
Where LoggedDate Between GetDate() - 7 and GetDate() - 1
) AS t WHERE t.rn=1
Order By
NewId()

SQL join conditional either or not both?

I have 3 tables that I'm joining and 2 variables that I'm using in one of the joins.
What I'm trying to do is figure out how to join based on either of the statements but not both.
Here's the current query:
SELECT DISTINCT
WR.Id,
CAL.Id as 'CalendarId',
T.[First Of Month],
T.[Last of Month],
WR.Supervisor,
WR.cd_Manager as [Manager], --Added to search by the Manager--
WR.[Shift] as 'ShiftId'
INTO #Workers
FROM #T T
--Calendar
RIGHT JOIN [dbo].[Calendar] CAL
ON CAL.StartDate <= T.[Last of Month]
AND CAL.EndDate >= T.[First of Month]
--Workers
--This is the problem join
RIGHT JOIN [dbo].[Worker_Filtered]WR
ON WR.Supervisor IN (SELECT Id FROM [dbo].[User] WHERE FullName IN(#Supervisors))
or (WR.Supervisor IN (SELECT Id FROM [dbo].[User] WHERE FullName IN(#Supervisors))
AND WR.cd_Manager IN(SELECT Id FROM [dbo].[User] WHERE FullNameIN(#Manager))) --Added to search by the Manager--
AND WR.[Type] = '333E7907-EB80-4021-8CDB-5380F0EC89FF' --internal
WHERE CAL.Id = WR.Calendar
AND WR.[Shift] IS NOT NULL
What I want to do is either have the result based on the Worker_Filtered table matching the #Supervisor or (but not both) have it matching both the #Supervisor and #Manager.
The way it is now if it matches either condition it will be returned. This should be limiting the returned results to Workers that have both the Supervisor and Manager which would be a smaller data set than if they only match the Supervisor.
UPDATE
The query that I have above is part of a greater whole that pulls data for a supervisor's workers.
I want to also limit it to managers that are under a particular supervisor.
For example, if #Supervisor = John Doe and #Manager = Jane Doe and John has 9 workers 8 of which are under Jane's management then I would expect the end result to show that there are only 8 workers for each month. With the current query, it is still showing all 9 for each month.
If I change part of the RIGHT JOIN to:
WR.Supervisor IN (SELECT Id FROM [dbo].[User] WHERE FullName IN (#Supervisors))
AND WR.cd_Manager IN(SELECT Id FROM [dbo].[User] WHERE FullName IN(#Manager))
Then it just returns 12 rows of NULL.
UPDATE 2
Sorry, this has taken so long to get a sample up. I could not get SQL Fiddle to work for SQL Server 2008/2014 so I am using rextester instead:
Sample
This shows the results as 108 lines. But what I want to show is just the first 96 lines.
UPDATE 3
I have made a slight update to the Sample. this does get the results that I want. I can set #Manager to NULL and it will pull all 108 records, or I can have the correct Manager name in there and it'll only pull those that match both Supervisor and Manager.
However, I'm doing this with an IF ELSE and I was hoping to avoid doing that as it duplicates code for the insert into the Worker table.
The description of expected results in update 3 makes it all clear now, thanks. Your 'problem' join needs to be:
RIGHT JOIN Worker_Filtered wr on (wr.Supervisor in(#Supervisors)
and case when #Manager is null then 1
else case when wr.Manager in(#Manager) then 1 else 0 end
end = 1)
By the way, I don't know what you are expecting the in(#Supervisors) to achieve, but if you're hoping to supply a comma separated list of supervisors as a single string and have wr.Supervisor match any one of them then you're going to be disappointed. This query works exactly the same if you have = #Supervisors instead.

Last Date Attended from 2 Tables SQL Server

I have searched the forum, and couldn't find an answer. So I apologize if this is out there. This seems simple in my mind, however, I can't seem to get the correct code.
I have 2 tables. STUDENT_TERMS_VIEW table holds STTR_STUDENT, STTR_TERM and TERMS table, holds the TERM_END_DATE. I need to find a way to select the student's last term based on MAX(TERM_END_DATE), but I get STTR_TERM duplicate rows per student. I need to get 1 row per student and their last term attended.
EDIT: Ok so both tables are linked by TERM.
View Code Here
As you can see, I am getting duplicate TERMS for the same student, even though I am pulling MAX(TERM_END_DATE)
SELECT * FROM
(SELECT STUDENT_TERMS_VIEW.STTR_STUDENT,
STUDENT_TERMS_VIEW.STTR_TERM,
TERMS.TERM_END_DATE
FROM STUDENT_TERMS_VIEW
JOIN STUDENT_TERMS_VIEW ON TERMS.TERMS_ID = STUDENT_TERMS_VIEW.STTR_TERM
ORDER BY TERMS.TERM_END_DATE DESC,STUDENT_TERMS_VIEW.STTR_STUDENT)
GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT
Your query is getting the max of the combination of (STTR_STUDENT and STTR_TERM). If you only want to get the max term of each student, you should only GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT. Try the query below.
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE)
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
If you also need to get the term, join it back to STUDENT_TERMS_VIEW and TERMS.
SELECT s.STTR_STUDENT, s.STTR_TERM, t.TERM_END_DATE
FROM (
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE) AS 'MaxDate'
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
) a
JOIN STUDENT_TERMS_VIEW s ON s.STTR_STUDENT = a.STTR_STUDENT
JOIN TERMS t ON t.TERMS_ID = s.STTR_TERM AND t.TERM_END_DATE = a.TERM_END_DATE

Solving Duplicated in Access

i had a table depends on more than one tables and i get this final
ScrrenShoot have a look in picture
i need to choose from values if firstdate duplicated in specific criteria
for ex . i need one row for 18.2.2016 / max value ( get the greater one ) / min value (get the less one )
You need to provide us with better information, but here is what I think you're looking for.
You need a separate query for each min/max value you want to find. Where you see "MyTable" you need to replace it with the object name shown in the screenshot.
Query 1 "Max"
SELECT MyTable.FirstOfDate, Max(MyTable.MaxValue) AS MaxOfMaxValue
FROM MyTable
GROUP BY MyTable.FirstOfDate;
Query 2 "Min"
SELECT MyTable.FirstOfDate, Min(MyTable.MinValue) AS MinOfMinValue
FROM MyTable
GROUP BY MyTable.FirstOfDate;
Query 3 "Merge"
SELECT DISTINCT MyTable.FirstOfDate, Max.MaxOfMaxValue, Min.MinOfMinValue
FROM (MyTable
INNER JOIN [Max] ON MyTable.FirstOfDate = Max.FirstOfDate)
INNER JOIN [Min] ON MyTable.FirstOfDate = Min.FirstOfDate
GROUP BY MyTable.FirstOfDate, Max.MaxOfMaxValue, Min.MinOfMinValue;

Resources