MySQL - Is it possible to achieve this using SQL? - sql

Imagine you've got a table with 2 columns: ID and NAME. ID is simply a number, incrementing for each row (as you'd expect). NAME is some random varchar string. NAME can be same for different rows. Now, imagine you want to get the 3 latest occurences in this table, where NAME only may occur once.
For example, if you've got this data:
ID NAME
1 HELLO
2 TEST
3 HELLO
4 HELLO
5 QWERTY
6 HELLO
Then the result of the question should be:
6 HELLO
5 QWERTY
2 TEST
Is it possible achieve this on SQL level?

SELECT
MAX(ID),
Name
FROM
table
GROUP BY
Name
ORDER BY
MAX(ID) desc
LIMIT 3

SELECT MAX(ID), NAME
FROM THAT_TABLE
GROUP BY NAME
See: GROUP BY (Aggregate) Functions

I suppose, you need to use "DISTINCT" for the "name" column:
SELECT DISTINCT name, id FROM table_name ORDER BY id DESC LIMIT 3;
Another way to achieve this is to use "GROUP BY" for "name" (see another answer)

Related

Order By clause in sql server

Suppose, there is a table and I need to sort one of its column (name) alphabetically and at the same time I want to sort it by using ID column in asc order based on the condition ( rows that have same name). So, I failed to understand how this will work. Once the records will be sorted by column (name) then will it sort all rows by using id column?
Can someone explain how actually order by clause works in this case
select name,
id
from hack h
order by name,
id
use order by name, id
select name,
id
from hack
order by name,
id
I just tried to understand what you want to know, you want to realize how it happens when the order by clause have two or more columns ,am I right? Let's go to an example,
the first column is id and the second is name,
2 A
5 B
6 A
3 A
1 B
the result of SQL "select name,id from hack order by name,id" will get the result as below
A 2
A 3
A 6
B 1
B 5
see, it will sort first by name column, and then sort id in the same name value group.
That's it ,did I make it clear?
This answers the original question.
In the code you posted:
substring(name, len(name) - 2, len(name))
returns the last 3 characters of the name.
So you are sorting by these last 3 characters and not by name.
When there are 2 names with the same last 3 characters these will be sorted by id.
If there are more than one column names after "order by" keyword, the system orders the records according to the first column just after order by.

How do I generate a table of IDs which have only one attribute each?

I have a table that looks like this
id attribute
1 a
1 a
2 b
2 a
And I want to collect all of the IDs which have ONLY attribute a. So in the example case:
id
1
My initial thought was to use a where, but that would return:
id
1
1
2
Because 2 also has an "a" attribute in one instance.
P.S. I realize the phrasing of the title is ambiguous; maybe there's a better term than attribute to use in this case?
ohh I just saw hive but this is pretty standard sql give it a try.
SELECT
ID
FROM
TABLENAME
GROUP BY
ID
HAVING
COUNT(DISTINCT attribute) = 1
Having is like a where statement after the GROUP BY aggregation has occurred.
HiveQL equivalent of SQL using group by ,having and distinct
select id from (select id,count(distinct attribute) cnt from table_actual group by id having cnt='1') tableouter;

Sql to get unique rows

I have a table as below.
OId CustId CustSeq
1 A 10
1 A 20
2 A 10
2 A 20
I'm trying to extract unique records as below.
OId CustId CustSeq (Different OIds with different CustSeqs)
1 A 10
2 A 20
May I know how I could come out the query to extract like above?
Just use DISTINCT. That's what it was desgined for although group by will work.
http://www.techonthenet.com/oracle/distinct.php
SELECT DISTINCT OID, CUSTID, CUSTSEQ
FROM TABLE_NAME
Use DISTINCT, and also use Group By for the 2 columns CustId & CustSeq
Check here for example Is it possible to GROUP BY multiple columns using MySQL?

How can I write this SQL SELECT query for this table?

I have this situation in a certain table:
id | name
1 'Test'
2 'Test'
3 'Test'
How can I make a query to SELECT by distinct the name? I also need the ID column, even if I get the first occurrence of the element, e.g. "if the name column repeats, give me the first record with this repetition."
select name, MIN(ID)
from aCertainTable
group by name

How to select 10 rows below the result returned by the SQL query?

Here is the SQL table:
KEY | NAME | VALUE
---------------------
13b | Jeffrey | 23.5
F48 | Jonas | 18.2
2G8 | Debby | 21.1
Now, if I type:
SELECT *
FROM table
WHERE VALUE = 23.5
I will get the first row.
What I need to accomplish is to get the first and the next two rows below. Is there a way to do it?
Columns are not sorted and WHERE condition doesn't participate in the selection of the rows, except for the first one. I just need the two additional rows below the returned one - the ones that were entered after the one which has been returned by the SELECT query.
Without a date column or an auto-increment column, you can't reliably determine the order the records were entered.
The physical order with which rows are stored in the table is non-deterministic.
You need to define an order to the results to do this. There is no guaranteed order to the data otherwise.
If by "the next 2 rows after" you mean "the next 2 records that were inserted into the table AFTER that particular row", you will need to use an auto incrementing field or a "date create" timestamp field to do this.
If each row has an ID column that is unique and auto incrementing, you could do something like:
SELECT * FROM table WHERE id > (SELECT id FROM table WHERE value = 23.5)
If I understand correctly, you're looking for something like:
SELECT * FROM table WHERE value <> 23.5
You can obviously write a program to do that but i am assuming you want a query. What about using a Union. You would also have to create a new column called value_id or something in those lines which is incremented sequentially (probably use a sequence). The idea is that value_id will be incremented for every insert and using that you can write a where clause to return the remaining two values you want.
For example:
Select * from table where value = 23.5
Union
Select * from table where value_id > 2 limit 2;
Limit 2 because you already got the first value in the first query
You need an order if you want to be able to think in terms of "before" and "after".
Assuming you have one you can use ROW_NUMBER() (see more here http://msdn.microsoft.com/en-us/library/ms186734.aspx) and do something like:
With MyTable
(select row_number() over (order by key) as n, key, name, value
from table)
select key, name, value
from MyTable
where n >= (select n from MyTable where value = 23.5)