How to obtain data from sub query that has self join? - mysql

my table:
friends(uid_1 int, uid_2 int)
This is my query :
SELECT a.uid_1
, a.uid_2 as a2
, b.uid_1 as b1
, b.uid_2
from friend a
join friend b
on a.uid_1 = b.uid_2;
I want to obtain a2 and b1 from query for other purposes
So this query now:
Select a2,b1
from (SELECT a.uid_1,a.uid_2 as a2,b.uid_1 as b1,b.uid_2
from friend a join
friend b
on a.uid_1=b.uid_2
)
does not work. How do I obtain certain data from a range of displayed data?

Number 1, you are just missing with a Alias name for your sub query as below-
Select a2,b1
from (
SELECT a.uid_1,a.uid_2 as a2,b.uid_1 as b1,b.uid_2
from friend a join
friend b
on a.uid_1=b.uid_2
) A -- added A as a Alias
But number 2, not sure what you are trying to do with the JOIN as your query with implemented JOIN conditions is simply equivalent to below query-
SELECT *
FROM friend
WHERE uid_1 = uid_2

You need table name alias for the subquery eg : Select ... FROM (subquery ) T
then you can refer the subquery content with a fully qualified name
Select T.a2, T.b1
from (SELECT a.uid_1,a.uid_2 as a2, b.uid_1 as b1, b.uid_2 b2
from friend a join
friend b
on a.uid_1=b.uid_2
) T

You were just missing alias
Select a2,b1
from (SELECT a.uid_1,a.uid_2 as a2,b.uid_1 as b1,b.uid_2
from friend a join
friend b
on a.uid_1=b.uid_2
) as temp -- here it is

Related

How to select multiple columns in a select sub-query in MySQL database?

I am trying to get a row of another table as a sub-query of the SELECT query.
SELECT g.ip, g.version, t.testid, t.status, m.rundate, t.runid , (select * from B where runid=t.runid and testid=t.testid)
FROM Tests t, Master m, Env g
WHERE t.runid=m.runid
AND t.runid=g.runid
AND g.version = "1.2.3"
AND t.testid like "%test_name%"
AND g.ip in ("198.18.111.222")
order by m.rundate desc;
How can this be achieved?
Thanks!
Try with this:
SELECT g.ip, g.version, t.testid, t.status, m.rundate, t.runid , c.* from B c
Join Tests t on t.runid =t.testid
join Master m on t.runid=m.runid
join Env g on t.runid=g.runid
WHERE g.version = "1.2.3" AND t.testid like "%test_name%"
AND g.ip in ("198.18.111.222")
order by m.rundate desc;
at line 2 if there is any id in B table which matches with the id in Tests
replace t.runid = t.testid (suppose if you have runid in B table which relates to test table testid then replace with c.runid = t.testid)to the requirement in which the B table and tests table are satisfying the scenario of matching ID's(PK and FK).

SQL INNER JOIN / Unknown column C.book in On Clause

https://www.db-fiddle.com/f/nCgygDjwYXZnWQ28LL7kMi/0
Goal:
Select copy.owner of people that own both books by "Scott Kelby" with different ISBN numbers
Hey guys, in order to derive the book table in the example on db-fiddle, I had actually used a bunch of inner join statements.
Now that I have acquired the book table how can I check that the c.owner owns both copies of the book?
I tried to use
SELECT DISTINCT
C.owner
FROM
copy C,
copy C1
INNER JOIN (
SELECT
B.authors,
B.ISBN13
FROM
book B
INNER JOIN(
SELECT
B1.authors
FROM
book B1
GROUP BY
B1.authors
HAVING (COUNT(B1.authors) > 1)
) B1
ON B.authors = B1.authors) B
ON C.book = B.ISBN13 AND C1.book = B.ISBN13 AND C1.book <> C.book;
However, if I try to reference to two table in the 2nd line of code, i will get the error unknown column in ON clause forcing me to remove copy C1 from the query.
You can try below -
select owner
from book b inner join copy c
on b.isbn13=c.book
group by owner
having count(distinct isbn13)=2

repeated rows in json_agg() in query with 2 lateral joins

I have a strange result when performing a lateral join on a query
I have the following table structure
task->id
comment -> id , taskId, comment
tasklink -> taskId, type, userid
with a single task record (id 10), 1 comment record ("row1", "a test comment") and 5 tasklink records (all with taskid 10)
I expected this query
select task.id,
json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments,
json_agg(json_build_object('type',b.type, 'user',b.userid)) as users
FROM task
left join lateral (select c.* from comment c where task.id = c.taskid) c on true
left join lateral (select b.* from taskuserlink b where task.id = b.taskid) b on true
where task.id = 10
GROUP BY task.id ;
to return
id | comments | users
---------------------------------------------------------------------
10 "[{"id":"row1","user":"a test comment"}]" "[{"type":"updatedBy","user":1},"type":"closedBy","user":5},"type":"updatedBy","user":5},"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"
instead, I got this
id | comments | users
10 "[{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"}]" "[{"type":"updatedBy","user":1},{"type":"closedBy","user":5},{"type":"updatedBy","user":5},{"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"
ie , for every link row, the comment row is duplicated
I am thinking that I am missing something really obvious, but as I have only just started using Postgres (and sql ) I'm a little stumped
I would appreciate some guidance on where I'm going wrong
Move the aggregates into subqueries:
select id, comments, users
from task t
left join lateral (
select json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments
from comment c
where t.id = c.taskid
) c on true
left join lateral (
select json_agg(json_build_object('type',b.type, 'user',b.userid)) as users
from taskuserlink b
where t.id = b.taskid
) b on true
DbFiddle.

Improving query speed: simple SELECT from SELECT in huge table

I have a table contains 3 columns : age , name , nickname
I would like to get only the names (+age) where the name+age does not exist at all in nickname+age.
For example : if table : DETAILS contains 2 rows :
age: 5 , name: suzi, nickname: suzi
age:2 , name : gil, nickname: g
query will return : age:2 , name : gil
SELECT d1.AGE, d1.NAME
FROM DETAILS d1
WHERE d1.NAME NOT IN (SELECT d2.NICKNAME FROM DETAILS d2 WHERE d2.AGE = d1.AGE)
This query runs only on small data.
Any idea how to improve it?
The critical point in SQL query performance is using index. So you have to have the index in the querying/joining columns and you need to use it (via join).
E.g. query:
SELECT DISTINCT D1.AGE, D1.NAME
FROM DETAILS D1 LEFT JOIN DETAILS D2 ON D1.AGE = D2.AGE
WHERE D1.NAME <> D2.NICKNAME
Note that you have to create indexes on columns AGE, NAME, AND NICKNAME beforehand to fully benefit from this query.
Use Left Join/Left Outer Join instead of WHERE ... NOT IN ...
The orders of execution of SQL
FROM
ON
OUTER
WHERE
GROUP BY
CUBE | ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
You can easily get the result by this:
SELECT d1.AGE,
CASE WHEN d1.NAME IS NULL
THEN d1.NIKCNAME ELSE d1.NAME END as [NewName]
FROM DETAILS d1
INNER JOIN DETAILS d2
ON d1.AGE = d2.AGE
WHERE d2.NAME <> d1.NICKNAME

Add prefix text to select statement

I am trying to run a select statement on two different servers that have some matching primary keys. I want to be able to select the primary key but add the prefix 'A' to every record
ex:
ID "to this" ID
1 A1
2 A2
3 A3
This is what I have for the query
select 'A' + CAST (a.id AS VARCHAR(25)) as ID,a.*,':', b.*,':',c.*,':', d.*,':', e.*,'REPORTDT', g.*
from labgen.order_ a
join patient b on a.id = b.chart
join insurance c on b.ins1 = c.code
join client d on d.num = a.client1
join salesgrp e on d.salesgroup = e.num
join reportdt g on a.accession = g.accession
Try this in the select statement:
select CONCAT('A', a.id) as ID, a.*,':', //etc
This link will also help.