SQL Multiple Joins not working as expected - sql

I have following query not working when I try to join all 4 tables (It is taking over an hour to run, I have to eventually kill the query without any data being returned).
It works when Table 1,2 & 3 are joined AND Then If I try Table 1,2 & 4 join but not when I attempt to join all 4 tables below.
Select * From
(Select
R.ID, R.MId, R.RId, R.F_Name, R.F_Value, FE.FullEval, M.Name, RC.CC
FROM Table1 as R
Inner Join Table2 FE
ON R.ID = FE.RClId and R.MId = FE.MId and R.RId = FE.RId
Inner Join Table3 as M
ON R.MId = M.MId and FE.MId = M.MId
Inner Join Table4 as RC
ON R.RId = RC.RId and FE.RId = RC.RId and FE.Date = RC.Date
) AS a
NOTE:
1) RId is not available in table3.
2) MId is not available in table4.
Thanks for help.

Since you mentioned that you don't have permission to view the query plan, try breaking down into each table join. You can also check which table join is taking time to retrieve records. From there, you can investigate the data why it's taking time. It may be because of non-availability of column keys in Table 3 and Table 4?
WITH Tab1_2 AS
(SELECT r.ID, r.MId, r.RId, r.F_Name, r.F_Value, fe.FullEval, fe.date
FROM Table1 as r
INNER JOIN Table2 fe
ON r.ID = fe.RClId
AND r.MId = fe.MId
AND r.RId = fe.RId
WHERE ... -- place your conditions if any
),
Tab12_3 AS
(SELECT t12.*, m.Name
FROM Tab1_2 t12
INNER JOIN Table3 as m
ON t12.MId = m.MId
WHERE ... -- place your conditions if any
),
Tab123_4 AS
(SELECT t123.ID, t123.MId, t123.RId, t123.F_Name, t123.F_Value, t123.FullEval, rc.CC
FROM Tab12_3 t123
INNER JOIN Table4 as rc
ON t123.RId = rc.RId
AND t123.Date = rc.Date
WHERE ... -- place your conditions if any
)
SELECT *
FROM Tab123_4 t1234

Related

Duplicate data from select statement

I want to make a stress test to a procedure than generate a .csv file.
The problem is that i have not enough data, so i want to duplicate data in my sql select .
The query look like this:
SELECT P.FST_NAME,
P.LAST_NAME,
P.EMAIL_ADDR,
P.PERSON_UID,
PR.FST_NAME PRSP_FST_NAME,
PR.LAST_NAME PRSP_LAST_NAME,
M.X_BAPRO_DT_01,
M.X_BAPRO_DT_02,
M.X_BAPRO_DT_03,
M.X_BAPRO_MONTO,
M.X_BAPRO_NUM_01,
M.X_BAPRO_NUM_02,
M.X_BAPRO_NUM_03,
M.X_BAPRO_TEXT_01,
M.X_BAPRO_TEXT_02,
M.X_BAPRO_TEXT_03,
M.X_BAPRO_TEXT_04,
M.X_BAPRO_TEXT_05
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
WHERE
C.ROW_ID <> p_row_id
So, This query return about 100 records, i want to retrive 1000 records and i dont really care if the data is duplicated.
You can add a cross join:
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
cross join (select 1 as n from dual union all
select 2 from dual
. . .
) x
You can also use the VALUE clause to construct the little "muliplier"-table as shown below:
SELECT ...
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
cross join (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) tabl(n)

How to select multiple many to many in relation with a single table

I'm currently working with database, but I've got stuck with a select query.
However, I'm not database expert.
The query should return the data from a table that has two relationships of many to many.
This is my tables Diagram that would shows the concept of my question
The Select Query should View three columns, which are VidTbl.Name, ActorTbl.Name and SubTitelTbl.name.
So, I've read and search in the Internet and I've given tries
First try
SELECT
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId
UNION all
SELECT
VidTbl.NAME AS Video_Titel_Name,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId
The Result I've got, it was wrong
Then I tried another way to solve this problem, but again I've got another error
second try
SELECT Temp1.*
From (SELECT VidTbl.Id AS Video_Id,
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId) AS Temp1
SELECT Temp2.*
FROM (SELECT VidTbl.Id AS Video_Id,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId) AS Temp2
SELECT *
FROM VidTbl
INNER JOIN Temp1
on Temp1.Video_Id = VidTbl.Id
INNER JOIN Temp2
on Temp2.Video_Id = VidTbl.Id
The error, I've got in the last select that was wrong
Thanks a lot for your help any ways
I wish that my question is clear and useful
Thanks again.
You are close. This should work...
SELECT
VidTbl.Name,
ActorTbl.Name,
SubTitelTbl.name
FROM VidTbl
INNER JOIN ActorInVid ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl ON ActorTbl.Id = ActorInVid.FKActorId
INNER JOIN SubTitelInVid ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl ON SubTitelTbl.Id = SubTitelInVid.FKSTId
SELECT DISTINCT vt.Name, at.Name, st.Name
FROM VidTbl vt
JOIN ActionInVid aiv ON aiv.VidId = vt.Id
JOIN SubtitleInVid siv ON siv.VidId = vt.Id
JOIN ActorTbl at ON at.Id = aiv.ActorId
JOIN SubTitleTbl st ON st.Id = siv.STId

PostgreSQL - INNER JOIN two tables with a LIMIT

I've seen this post which almost coincides with my question but my specific problem is that I need to put a limit to the third table/query, as in LIMIT 15, for example. Is there an easy way to achieve this? Thanks!
EDIT
My SQL SELECT statement would look something like this:
SELECT t2.name AS user_name, t3.name AS artist_name
FROM tbl1 t1
INNER JOIN tbl2 t2 ON t1.t1able_id = t2.id
INNER JOIN (SELECT * FROM tbl3 WHERE artist_id = 100 limit 15) t3
ON t2.id = t3.artist_id
WHERE t1.kind = 'kind'
To clarify: It's just a matter of joining two tables but the second table has two states. First state as a "common user" and the next state as an "artist" (both using the same table, e.g. users).
Try this query:
select *
from
tableA a
inner join
tableB b
on a.common = b.common
inner join
(select * from tableC order by some_column limit 15) c
on b.common = c.common
Few days ago I searched for such answer and Postgresql provides to do it smoothly with rank().
My goal was to get last 3 submitted annual report files before commercial firm got started its first insolvency process.
SELECT * FROM
(
SELECT r.id, f.id AS id_file, f.file_date, min(p.process_started) AS "first_process_started",
rank() OVER (PARTITION BY r.id ORDER BY f.file_date DESC) AS "rank"
FROM registry r
INNER JOIN files f ON (r.id = f.id_registry)
INNER JOIN processes p ON (r.id = p.id_registry)
WHERE
r.type = 'LIMITED_LIABILITY_COMPANY'
AND f.file_type = 'ANNUAL_REPORT')
AND p.process_type = ('INSOLVENCY')
GROUP BY r.id, f.id, f.file_date
HAVING f.file_date <= min(p.process_started)
) AS ranked_files
WHERE rank <= 3

SQL -- Adding a constraint to a results row in an existing query

The following query gives me a one row result
Select Sum(Actions) From
(
Select
Count(t.Create_Dtime) As Actions
From Player_Tapjoy T
Inner Join Player_Source S
On (T.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
And F.Feature_Name ='Try BC')
Where Trunc(t.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
Union All
Select
Count(a.Create_Dtime) As Actions
From Player_Aux_Pt A
Inner Join Player_Source S
On (A.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
and f.feature_name = 'TryBC')
Where A.Site = 'AppCircle'
And Trunc(A.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
)
I now want to add in a constraint to the result where: only users that have created an account before Sep 12,2012.
In my database language: only users that have a trunc(create_dtime) < To_Date('2012-sep-12','yyyy-mon-dd') . This trunc(create_dtime) date comes from the player table.
Could I map this player table to the current table by using another inner join?
Your requirement isn't completely clear and obviously I have had to guess about your data model. I'm assuming the Player table has one row per Player_Id i.e. it is the primary key end of foreign key relationships to the tables you're querying.
I have changed the inner query so it just returns a set of rows rather than aggregations. Then I join the inline view (aliased q) with the Player table and use a COUNT() rather a SUM() to get the figure.
Select count(Player_Id) From
(
Select
T.Player_Id
From Player_Tapjoy T
Inner Join Player_Source S
On (T.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
And F.Feature_Name ='Try BC')
Where Trunc(t.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
Union All
Select
A.Player_Id
From Player_Aux_Pt A
Inner Join Player_Source S
On (A.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
and f.feature_name = 'TryBC')
Where A.Site = 'AppCircle'
And Trunc(A.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
) q
join player p
on (p.Player_Id = q.Player_Id)
where Trunc(p.Create_Dtime) < To_Date('2012-sep-12','yyyy-mon-dd')
This may not be the exact result you need, for the reasons I gave at the top, but it should point you in the right directon.

Left Join, Order by, MySQL Optimization

I have a query like this:
SELECT m...., a...., r....
FROM 0_member AS m
LEFT JOIN 0_area AS a ON a.user_id = (SELECT user_id
FROM `0_area`
WHERE user_id = m.id
ORDER BY sec_id ASC LIMIT 1)
LEFT JOIN 0_rank as r ON a.rank_id = r.id
WHERE m.login_userid = '$username'
The idea is to get the first row from 0_area table and hence the attempted inner join. However, it is not working as expected.
Between 0_area and 0_member, 0_member.id = 0_area.user_id. However, there are multiple rows of 0_area.user_id and I want the row having the lowest value of sec_id.
Any help please?
SELECT m...., a...., r....
FROM 0_member AS m
LEFT JOIN (SELECT user_id, min(sec_id) minsec
FROM `0_area`
GROUP BY user_id) g1 on g1.user_id=m.id
LEFT JOIN 0_area AS a ON a.user_id = g1.user_id and a.sec_id=minsec
LEFT JOIN 0_rank as r ON a.rank_id = r.id
WHERE m.login_userid = '$username'