Sort by string with two columns - sql-order-by

I have a table 'relationships' like below
id | user_1_nick | user_2_nick
1 peter kevin
2 jake peter
3 peter abby
4 aaron abby
5 abby kevin
So if Peter is logged in his 'friends' will be shown as below
1 abby
2 jake
3 kevin
And Abbys 'friends' as below
1 aaron
2 kevin
3 peter
I hope you get me.
Thanks in advance.
UPDATE
My current query looks like this:
SELECT * FROM relationships AS r
LEFT JOIN members AS m
ON (r.user_2 = m.hash AND r.user_2 != '$userhash')
OR (r.user_1 = m.hash AND r.user_1 != '$userhash')
WHERE (user_2 = '$userhash' OR user_1 = '$userhash')
AND accepted = '1'

In MySQL
You have to filter the friends in both directions and merge the results as illustrated below.
So the friends of peter could be fetched with the query:
SELECT A.FRIENDS FROM
(SELECT user_2_nick friends FROM relationships
WHERE user_1_nick='peter'
UNION
SELECT user_1_nick friends FROM relationships
WHERE user_2_nick='peter') A
ORDER BY A.FRIENDS;
And for abby with:
SELECT A.FRIENDS FROM
(SELECT user_2_nick friends FROM relationships
WHERE user_1_nick='abby'
UNION
SELECT user_1_nick friends FROM relationships
WHERE user_2_nick='abby') A
ORDER BY A.FRIENDS;
Here is the SQL FIDDLE DEMO

Related

Google Sheets Query | Use aggregation function count() in where clause

Say I've got a list of names in column A.
Chandler
Ross
Monika
Joey
Phoebe
Rachel
Ross
Monika
Joey
Ross
Monika
Joey
Entering the below formula, produces the below result
=query(A:A, "select A, count(A) group by A")
count
Chandler
1
Joey
3
Monika
3
Phoebe
1
Rachel
1
Ross
3
Can I somehow make the below formula work and produce the below table?
=query(A:A, "select A, count(A) where count(A)>2 group by A")
count
Joey
3
Monika
3
Ross
3
You can't add aggregate function to WHERE clause, so using one query it is not possible. But you can add another QUERY:
=QUERY(query(A:A, "select A, count(A) group by A"),"SELECT * WHERE Col2>2")

Oracle Query Prevent Displayed Duplicate Record

Let's say i have a table structure like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
2 DARK Kindergarten 111 1
3 Knight NY University 3
4 Knight LA Senior HS 2
5 JOHN HARVARD 3
so, how to diplay all of the data above into like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
3 Knight NY University 3
5 JOHN HARVARD 3
my purpose is want to display data with the max of codeschool, but when i tried with my query below :
SELECT NAME, SCHOOLNAME, MAX(CODESCHOOL) FROM TABLE GROUP BY NAME, SCHOOLNAME
but the result is just like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
2 DARK Kindergarten 111 1
3 Knight NY University 3
4 Knight LA Senior HS 2
5 JOHN HARVARD 3
maybe it caused by the GROUP BY SCHOOLNAME, when i tried to not select SCHOOLNAME, the data displayed just like what i expected, but i need the SCHOOLNAME field for search condition in my query
hope you guys can help me out of this problem
any help will be appreciated
thanks
Using some wacky joins you can get a functional get max rows per category query.
What you essentially need to do is to join the table to itself and make sure that the joined values only contain the top values for the CODESCHOOL column.
I've also added a :schoolname parameter because you wanted to search by schoolname
Example:
SELECT
A.*
FROM
TABLE1 A
LEFT OUTER JOIN TABLE1 B ON B.NAME = A.NAME
AND B.CODESCHOOL < A.CODESCHOOL
WHERE
B.CODESCHOOL IS NULL AND
(
(A.SCHOOLNAME = :SCHOOLNAME AND :SCHOOLNAME IS NOT NULL) OR
(:SCHOOLNAME IS NULL)
);
this should create this output, note that dark has 2 outputs because it has 2 rows with the same code school which is the max in the dark "category"/name.
ID|NAME |SCHOOLNAME |CODESCHOOL
--| -----|----------------|----------
4|Knight|LA Senior HS | 2
5|JOHN |HARVARD | 3
2|DARK |Kindergarten 111| 1
1|DARK |Kindergarten 123| 1
It's not the most effective query but it should be more than good enough as a starting point.
Sidenote: I've been blatantly stealing this logic for a while from https://www.xaprb.com/blog/2007/03/14/how-to-find-the-max-row-per-group-in-sql-without-subqueries/
I am using an analytical window function ROW_NUMBER().
This will group (or partition) by NAME then select the top 1 CODESCHOOL in DESC order.
Select NAME,
SCHOOLNAME,
CODESCHOOL
From (
Select NAME,
SCHOOLNAME,
CODESCHOOL,
ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY CODESCHOOL DESC) as rn
from myTable)
Where rn = 1;

Select same column for different values on a different column

I did search the forum before posting this and found some topics which were close to the same issue but I still had questions so am posting it here.
EMP_ID SEQ_NR NAME
874830 3 JOHN
874830 4 JOE
874830 21 MIKE
874830 22 BILL
874830 23 ROBERT
874830 24 STEVE
874830 25 JERRY
My output should look like this.
EMP ID SEQ3NAME SEQ4NAME SEQ21NAME SEQ22NAME SEQ23NAME SEQ24NAME SEQ25NAME
874830 JOHN JOE MIKE BILL ROBERT STEVE JERRY
SELECT A.EMP_ID
,A.NAME SEQ3NAME
,B.NAME SEQ4NAME
FROM AC_XXXX_CONTACT A
INNER JOIN AC_XXXX_CONTACT B ON A.EMP_ID = B.EMP_ID
WHERE A.SEQ_NR = '03' AND B.SEQ_NR = '04'
AND B.EMP_ID = '874830';
The above query helped me get the below results.
EMP_ID SEQ3NAME SEQ4NAME
874830 JOHN JOE
My question is to get all the fields(i.e till seq nr = 25) should I be joining the table 5 more times.
Is there a better way to get the results ?
I m querying against the Oracle DB
Thanks for your help.
New Requirement
New Input
STU-ID SEM CRS-NBR
12345 1 100
12345 1 110
12345 2 200
New Output
stu-id crs1 crs2
12345 100 200
12345 110
Not tested since you didn't provide test data (from table AC_XXXX):
(using Oracle 11 PIVOT clause)
select *
from ( select emp_id, seq_nr, name
from ac_xxxx
where emp_id = '874830' )
pivot ( max(name) for seq_nr in (3 as seq3name, 4 as seq4name, 21 as seq21name,
22 as seq22name, 23 as seq23name, 24 as seq24name, 25 as seq25name)
)
;
For Oracle 10 or earlier, pivoting was done "by hand", like so:
select max(emp_id) as emp_id, -- Corrected based on comment from OP
max(case when seq_nr = 3 then name end) as seq3name,
max(case when seq_nr = 4 then name end) as seq4name,
-- etc. (similar expressions for the other seq_nr)
from ac_xxxx
where emp_id = '874830'
;
Or, emp_id doesn't need to be within max() if we add group by emp_id - which then will work even without the WHERE clause, for a different but related question.

displaying the top 3 rows

In the school assignment I'm working on I need to display the 3 criminals with the most crimes. But I'm having a few problems
Here's the code I have so far, and its output:
`Select Last, First, Count(Crime_ID)
From Criminals Natural Join crimes
Group by Last, First, Criminal_ID
order by Count(Crime_Id) Desc`
`LAST FIRST COUNT(CRIME_ID)
--------------- ---------- ---------------
Panner Lee 2
Sums Tammy 1
Statin Penny 1
Dabber Pat 1
Mansville Nancy 1
Cat Tommy 1
Phelps Sam 1
Caulk Dave 1
Simon Tim 1
Pints Reed 1
Perry Cart 1
11 rows selected `
I've been toying around with ROWNUM, but when I include it in the SELECT it won't run because of my GROUP BY. But If you put ROWNUM in the GROUP BY it just separates everything back out.
I just want to display the top 3 with the most crimes, which is weird because only 1 guy has more than 1 crime. Theoretically, more criminals would be added to the Database, but these are the tables given in the assignment.
select *
from
( Select Last, First, Count(Crime_ID)
From Criminals Natural Join crimes
Group by Last, First, Criminal_ID
order by Count(Crime_Id) Desc )
where ROWNUM <= 3;

Perl JOIN-like behavior in Oracle?

I have two tables, let's call them PERSON and NAME.
PERSON
person_id
dob
NAME
name_id
person_id
name
And let's say that the NAME table has data like:
name_id person_id name
1 1 Joe
2 1 Fred
3 1 Sam
4 2 Jane
5 2 Kim
I need a query (Oracle 10g) that will return
name_id names
1 Joe, Fred, Sam
2 Jane, Kim
Is there a simple way to do this?
Update:
According to the article that figs was kind enough to provide, starting in 9i you can do:
SELECT wmsys.wm_concat(dname) departments FROM dept;
For this example, the answer becomes:
SELECT name_id, wmsys.wm_concat(name) from names group by name_id
The short answer is to use a PL/SQL function. For more details, have a look in this post.

Resources