Get values and like values in SQL - sql

I have a SQL table that contains the following
ID AccountNumber Name
1 12345 Tony
2 123456 Mike
3 123458 Mike
4 45689 Tom
5 666999 Tim
6 6669997 Lisa
7 44455 Tim
8 78901 Matt
9 789011 Roger
What I need to do is show me all records where the Account Number begin with the same value (indeterminate number). For example. In this table, I'd want to select and display the following:
12345
123456
123458
666999
6669997
78901
789011
As you can see, it shows the each row where the AccountNumber matches or has the same beginning number. I haven't been able to find the proper query and would love any help.
Thanks!

The cases that you mention satisfy that the longer starts with the shorter. Here is a query that will get the shortest match for each account number:
select AccountNumber
from (select a.*, count(*) over (partition by ShortestAN) as numAN
from (select a.*,
(select top 1 a2.AccountNumber
from accounts a2
where a.AccountNumber like a2.AccountNumber + '%'
order by length(a2.AccountNumber) asc
) as ShortestAN
from accounts a
) a
) a
where numAN > 1
order by ShortestAN, AccountNumber;
The subquery finds the shortest account number that matches. The rest is just returning the ones where there is more than one match.

select a1.ID, a1.AccountNumber, a1.Name,
a2.ID, a2.AccountNumber, a2.Name
from Accounts a1
join Accounts a2 on LEN(a1.name) <= LEN(a2.name) and SUBSTRING(a2.name, 1, LEN(a1.name)) = a1.name
where /*are not same rows*/ a1.ID <> a2.ID

Would not an order by work if it were ordering as String?
SELECT AccountNumber, Id, Name
FROM Accounts
ORDER BY CAST(AccountNumber AS NVARCHAR(50))

Related

Find the people who are login 3 consecutive dates

LoginHistory table
Date Name Login
----------------------------------------
03/20/2021 Amy 1
03/20/2021 Lily 1
03/20/2021 Nancy 1
03/21/2021 Amy 1
03/21/2021 Lily 1
03/21/2021 Leo 1
03/22/2021 Amy 1
03/22/2021 Lisa 1
03/22/2021 Leo 1
03/23/2021 Lily 1
03/23/2021 Lisa 1
03/23/2021 Leo 1
I want to find the people and their login date who was login instance 3 times in consecutive dates. For example, my output should has Amy, because she was login 3/20,3/21 and 3/22. For Lily, she shouldn't be in my output, because even she login 3 times, the date(3/20,3/21 and 3/23) is not in consecutive order.
output should be:
Date Name Login
----------------------------------------
03/20/2021 Amy 1
03/21/2021 Amy 1
03/21/2021 Leo 1
03/22/2021 Amy 1
03/22/2021 Leo 1
03/23/2021 Leo 1
Thanks.
Based on the specific sample data provided, you could use analytic min and max to get the first and last date for each name, count the difference in days and the number of logins which must be 3 with 2 days between first and last date.
You haven't specific a RDBMS so the date functions may need amending as appropriate, however all RDBMS support the same functionality.
select date, name
from (
select *,
DateDiff(day,Min(date) over(partition by name),
Max(date) over(partition by name))diff,
Count(*) over(partition by name) qty
from t
)t
where diff=2 and qty=3
order by date;
To produce a table of the consecutive logins, you can first anchor your search on the action that is the last in the sequence. Then, you can join all the preceding dates to that original result:
with vals(v) as (
select 1
union all
select 2
)
select c2.* from (
select c.* from loginhistory c where
(select count(*) from loginhistory c1 cross join vals v
where c1.name = c.name and c.dt = c1.dt + interval '1' day * v.v) = 2
) t1
join loginhistory c2 on t1.name = c2.name and c2.dt <= t1.dt and (c2.dt + interval '2' day) >= t1.dt
order by c2.dt
select * from LoginHistory where name in (
select name
from LoginHistory
where date between <start> and <end> -- must be exactly three dates in the range
group by name
having count(distinct date) = 3
)

Finding the profile _id of person with maximum number of booking

I have a table as below. I wanted to find the profile_id with maximum number of Book_ids.
PROFILE_ID BOOK_ID
---------- --------------------
A1 001
A2 002
A3 003
A1 004
A3 005
A1 006
A4 007
A1 008
A2 009
A4 010
A3 011
So, first i need to count how many bookings are done by distinct profile_id and I did it like below
SQL>select profile_id, count(book_id) from book group by pro;
PROFILE_ID COUNT(BOOK_ID)
---------- --------------
A4 2
A3 3
A1 4
A2 2
but i wanted the query to return the profile_id with maximum count of booking. And for that, I used the below query
select profile_id from(select profile_id, count(book_id) no_of from book group by pro) deriv where deriv.no_of=max(deriv.no_of);
But it doesn't return the profile_id with max count of booking. I tried many different queries but it won't work.
Can anyone please help me. I am trying to write a general query but not for this particular table.
Little help would me a lot. Thank you
Try this query, i think you need the order by
select profile_id, count(book_id) as no_of
from book
group by pro
order by no_of desc
limit 1
Update to when you need more than 1 results:
SELECT profile_id,
count(book_id) AS no_of
FROM tbl1
GROUP BY profile_id
HAVING no_of =
(SELECT max(no_of)
FROM
(SELECT profile_id,
count(book_id) AS no_of
FROM tbl1
GROUP BY profile_id) tblAlias1)
In Oracle, you can use fetch first:
select profile_id, count(*)
from book
group by profile_id
order by count(*) desc
fetch first 1 row only;
If you want all profiles when there are duplicates, then one method is:
select profile_id, count(*)
from book
group by profile_id
order by count(*) desc
fetch first 1 row only with ties;
Oracle has supported fetch first since version 12C.
In older versions, you would use window functions:
select profile_id, cnt
from (select profile_id, count(*) as cnt,
rank() over (order by count(*) desc) as seqnum
from book b
group by profile_id
) b
where seqnum = 1;

Get number of different values in a column in Access

I've tried more or less all combinations of count and distinct (except the correct one :) ) in order to get the example below.
Input: table t1
NAME | FOOD
Mary | Apple
Mary | Banana
Mary | Apple
Mary | Strawberry
John | Cherries
Expected output:
NAME | FOOD
Mary | 3
John | 1
N.B. Mary has Apple in two rows but she has 3 as we have 3 different values in the column.
I only managed to get 4 in FOOD Column for her, but I need 3 :(
select a.name as NAME, a.count(name) as Food
from
(SELECT distinct NAME,Food from table)a
Start with a query which gives you unique combinations of NAME and FOOD:
SELECT DISTINCT t1.NAME, t1.FOOD
FROM t1
Then you can use that as a subquery in another where you can GROUP BY and Count:
SELECT sub.NAME, Count(*) AS [FOOD]
FROM
(
SELECT DISTINCT t1.NAME, t1.FOOD
FROM t1
) AS sub
GROUP BY sub.NAME;
select a.name, sum(a.FoodCount) from(
select distinct name,COUNT(food) as FoodCount from #t1 group by name, food ) as a group by a.name order by 2 desc

Nested order by/order by within order by in SQL

I am looking to sort my sql results via an sql query with presumably some sort of nested order by/order by within an order by clause
I have the following data:
TERM USER ITEM_NO SCORE
man sam 2 NULL
man sam 1 170
man jerry 1 100
man jerry 2 NULL
man sam 3 NULL
and I wish to obtain the following order for the results:
TERM USER ITEM_NO SCORE
man sam 1 170
man sam 2 NULL
man sam 3 NULL
man jerry 1 100
man jerry 2 NULL
The results must be sorted firstly by the score (stored only in item_no 1 for each user) descending. However any further items created by that user for the seleted term must also be picked up and inserted directly following and in item_no order.
My current query looks like this:
SELECT * FROM table WHERE term = 'man' ORDER BY SCORE DESC, ITEM_NO ASC
...however this simply results as follows:
TERM USER ITEM_NO SCORE
man sam 1 170
man jerry 1 100
man sam 2 NULL
man jerry 2 NULL
man sam 3 NULL
Thank you for any suggestions.
SELECT *,
(SELECT MAX(Score)
FROM TEST t2
WHERE t2.Term = t1.Term AND t2.User = t1.User GROUP BY t2.Term, t2. User) as max_score
FROM test t1
WHERE term = 'man'
ORDER BY max_score DESC, ITEM_NO ASC
Working DEMO
Or another solution with the same results (I think it has better performance, but you'd need to do some testing about that):
SELECT t1.*
FROM test t1
JOIN
(SELECT t2.Term, t2.User, score FROM Test t2 WHERE t2.Item_No = 1) t3
ON t1.Term = t3.Term AND t1.User = t3.User
ORDER BY t3.score DESC, t1.Item_No;
DEMO
select USER, ITEM_NO, SCORE from 'TABLE' order by 2, 3;
-- 2 is Column USER, 3 is Column ITEM_NO

Select query which returns exect no of rows as compare in values of sub query

I have got a table named student. I have written this query:
select * From student where sname in ('rajesh','rohit','rajesh')
In the above query it's returning me two records; one matching 'rajesh' and another matching: 'rohit'.
But i want there to be 3 records: 2 for 'rajesh' and 1 for 'rohit'.
Please provide me some solution or tell me where i am missing.
NOTE: the count of result of sub query is not fix there can be many words there some distinct and some multiple occurrence .
Thanks
Your requirements are not clear, and I'll try to explain why.
Let's define table students
ID FirstName LastName
1 John Smith
2 Mike Smith
3 Ben Bray
4 John Bray
5 John Smith
6 Bill Lynch
7 Bill Smith
Query with WHERE clause:
FirstName in ('Mike', 'Ben', 'Mike')
will return 2 rows only, because it could be rewritten as:
FirstName='Mike' or FirstName='Ben' or FirstName='Mike'
WHERE is filtering clause that just says if existing row satisfy given conditions or not (for each of rows created by FROM clause.
Let's say we have subquery that returns any number of non distinct FirstNames
In case if SQ contains 'Mike', 'Ben', 'Mike' using inner join you can get those 3 rows without problem
Select ST.* from Students ST
Inner Join (Select name from …. <your subquery>) SQ
On ST.FirstName=SQ.name
Result will be:
ID FirstName LastName
2 Mike Smith
2 Mike Smith
3 Ben Bray
Note data are not ordered by order of names returning by SQ. If you want that, SQ should return some ordering number, eg.:
Ord Name
1. Mike
2. Ben
3. Mike
In that case query should be:
Select ST.* from Students ST
Inner Join (Select ord, name from …. <your subquery>) SQ
On ST.FirstName=SQ.name
Order By SQ.ord
And result:
ID FirstName LastName
2 Mike Smith (1)
3 Ben Bray (2)
2 Mike Smith (3)
Now, let's se what will happen if subquery returns
Ord Name
1. Mike
2. Bill
3. Mike
You will end up with
ID FirstName LastName
2 Mike Smith (1)
6 Bill Lynch (2)
7 Bill Smith (2)
2 Mike Smith (3)
Even worse, if you have something like:
Ord Name
1. John
2. Bill
3. John
Result is:
ID FirstName LastName
1 John Smith (1)
4 John Bray (1)
5 John Smith (1)
6 Bill Lynch (2)
7 Bill Smith (2)
1 John Smith (3)
4 John Bray (3)
5 John Smith (3)
This is an complex situation, and you have to clarify precisely what requirement is.
If you need only one student with the same name, for each of rows in SQ, you can use something like SQL 2005+):
;With st1 as
(
Select Row_Number() over (Partition by SQ.ord Order By ID) as rowNum,
ST.ID,
ST.FirstName,
ST.LastName,
SQ.ord
from Students ST
Inner Join (Select ord, name from …. <your subquery>) SQ
On ST.FirstName=SQ.name
)
Select ID, FirstName, LastName
From st1
Where rowNum=1 -- that was missing row, added later
Order By ord
It will return (for SQ values John, Bill, John)
ID FirstName LastName
1 John Smith (1)
6 Bill Lynch (2)
1 John Smith (3)
Note, numbers (1),(2),(3) are shown to display value of ord although they are not returned by query.
If you can split the where clause in your calling code, you could perform a UNION ALL on each clause.
SELECT * FROM Student WHERE sname = 'rajesh'
UNION ALL SELECT * FROM Student WHERE sname = 'rohit'
UNION ALL SELECT * FROM Student WHERE sname = 'rajesh'
Try using a JOIN:
SELECT ...
FROM Student s
INNER JOIN (
SELECT 'rajesh' AS sname
UNION ALL
SELECT 'rohit'
UNION ALL
SELECT 'rajesh') t ON s.sname = t.sname
just because you've got a criteria in there two times doesn't mean that it will return 1 result per criteria. SQL engines usually just use the unique criteria - thus, from your example, there will be 2 criteria in IN clause: 'rajesh','rohit'
WHY do you need to return 2 results? are there two rajesh in your table? they should BOTH return then. You don't need to ask for rajesh twice for that to happen. What does your data look like? What do you want to see returned?
Hi i am query just as you give above and it give me all data that matches in the condition of in clause. just like your post
select * from person
where personid in (
'Carson','Kim','Carson'
)
order by FirstName
and its give me all records which fulfill this Criteria