LEFT JOIN DUPLICATING VALUES (QUERY WITH WHERE IN) - sql

I need to get rid of duplicated values return from a LEFT JOIN that I did, I'm such a beginner in SQL so I do hope you guys help me out!
SELECT *
,tm.TEAM_NAME
,up.USER_NAME OWNER_NAME
FROM NTTUS_INIT_TM_TASK_HEADER th
LEFT JOIN NTTUS_TEAM tm
ON th.TEAM_ID = tm.TEAM_ID
LEFT JOIN NTTUS_USER_PROFILE up
ON th.OWNER_ID = up.USER_ID
WHERE 1 = 1
AND INIT_ID IN(${arr.ids})

Actually from your description, it's hard to understand your table. But try this. If this doesn't work let me know
SELECT *
,tm.TEAM_NAME
,up.USER_NAME OWNER_NAME
FROM
NTTUS_INIT_TM_TASK_HEADER as th
LEFT JOIN
NTTUS_TEAM as tm ON th.TEAM_ID = tm.TEAM_ID
LEFT JOIN
NTTUS_USER_PROFILE as up ON th.OWNER_ID = up.USER_ID
WHERE
INIT_ID IN(${arr.ids})
Group By
th.*
,tm.TEAM_NAME
,up.USER_NAME OWNER_NAME
Having count(*) = 1

Related

Oracle SQL Takes Forever - Timeout Aborted

I have a query that is taking forever and won't bring any result (timeout). Not sure what's going on, it worked perfectly until very recently.
The amount of data on the tables is large but not extreme (200k rows, max cols: 8).
This is my query, can anyone help me see what I'm doing wrong please?
SELECT distinct
T.MY_ITEM_ID,
T.MY_ITEM_NAME,
T.MY_ITEM_DESCRIPTION,
T.CITY,
T.STATE,
T.COUNTRY,
Apr28.MY_ITEM_ID as ITEM_ID_03282022,
Apr28.MY_ITEM_NAME AS ITEM_NAME_03282022,
Apr28.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_03282022,
Apr06.MY_ITEM_ID as ITEM_ID_04062022,
Apr06.MY_ITEM_NAME AS ITEM_NAME_04062022,
Apr06.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_04062022,
Apr13.MY_ITEM_ID as ITEM_ID_04132022,
Apr13.MY_ITEM_NAME AS ITEM_NAME_04132022,
Apr13.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_04132022,
Apr20.MY_ITEM_ID as ITEM_ID_04202022,
Apr20.MY_ITEM_NAME AS ITEM_NAME_04202022,
Apr20.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_04202022,
May02.MY_ITEM_ID as ITEM_ID_05022022,
May02.MY_ITEM_NAME AS ITEM_NAME_05022022,
May02.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_05022022,
May09.MY_ITEM_ID as ITEM_ID_05092022,
May09.MY_ITEM_NAME AS ITEM_NAME_05092022,
May09.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_05092022,
May16.MY_ITEM_ID as ITEM_ID_05162022,
May16.MY_ITEM_NAME AS ITEM_NAME_05162022,
May16.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_05162022,
May23.MY_ITEM_ID as ITEM_ID_05232022,
May23.MY_ITEM_NAME AS ITEM_NAME_05232022,
May23.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_05232022,
May30.MY_ITEM_ID as ITEM_ID_05302022,
May30.MY_ITEM_NAME AS ITEM_NAME_05302022,
May30.MY_ITEM_DESCRIPTION AS MY_ITEM_DESCRIPTION_05302022
FROM MY_TABLE T
LEFT JOIN ITEM_Snap_03_28_2022 Apr28 ON T.KEY = Apr28.MY_KEY
LEFT JOIN ITEM_Snap_04_06_2022 Apr06 ON T.MY_KEY = Apr06.MY_KEY
LEFT JOIN ITEM_Snap_04_13_2022 Apr13 ON T.MY_KEY = Apr13.MY_KEY
LEFT JOIN ITEM_Snap_04_20_2022 Apr20 ON T.MY_KEY = Apr20.MY_KEY
LEFT JOIN ITEM_Snap_05_02_2022 May02 ON T.KEY = May02.MY_KEY
LEFT JOIN ITEM_Snap_05_09_2022 May09 ON T.KEY = May09.MY_KEY
LEFT JOIN ITEM_Snap_05_16_2022 May16 ON T.KEY = May16.MY_KEY
LEFT JOIN ITEM_Snap_05_23_2022 May23 ON T.KEY = May23.MY_KEY
LEFT JOIN ITEM_Snap_05_30_2022 May30 ON T.KEY = May30.MY_KEY
Thanks!

SQL-Get and replace minimum value of a query's field

I have the following query in Postgresql :
SELECT mq.nombre,sa.nombre,COUNT(DISTINCT(ae.numero_serie)),SUM(im.fin-im.inicio),MIN(pz.fecha_inicio)
FROM item_metraje AS im LEFT JOIN articulo_especificado AS ae ON (im.id_articulo_especificado = ae.id)
LEFT JOIN articulo AS a ON (ae.id_articulo = a.id)
LEFT JOIN serie_articulo AS sa ON (a.id_serie_articulo = sa.id)
LEFT JOIN reporte_perforacion AS rp ON (rp.id = im.id_reporte_perforacion)
LEFT JOIN pozo AS pz ON (pz.id=rp.id_pozo) LEFT JOIN proyecto AS p ON (p.id=pz.id_proyecto)
LEFT JOIN maquina_perforacion AS mq ON (mq.id = pz.id_maquina)
WHERE p.id = 2 GROUP BY mq.nombre,sa.nombre
and the result is :
However I want to put the minimum date for the rows that have the same value of the field 'nombre', for example for the value 'JM04' the three rows must have the date 2015-01-25 because it is the minimum value of the three rows.
Excuse me for my English and thanks for all.
You can use Window functions for this purpose. MIN(pz.fecha_inicio) over (partition by mq.nombre).
Therefore the final query is,
SELECT z.nombre1,z.nombre2,z.count,z.sum ,MIN(z.date) over (partition by z.nombre1) from
(SELECT mq.nombre as nombre1 ,sa.nombre as nombre2,COUNT(DISTINCT(ae.numero_serie)) as count,SUM(im.fin-im.inicio) as sum ,pz.fecha_inicio as date
FROM item_metraje AS im LEFT JOIN articulo_especificado AS ae ON (im.id_articulo_especificado = ae.id)
LEFT JOIN articulo AS a ON (ae.id_articulo = a.id)
LEFT JOIN serie_articulo AS sa ON (a.id_serie_articulo = sa.id)
LEFT JOIN reporte_perforacion AS rp ON (rp.id = im.id_reporte_perforacion)
LEFT JOIN pozo AS pz ON (pz.id=rp.id_pozo) LEFT JOIN proyecto AS p ON (p.id=pz.id_proyecto)
LEFT JOIN maquina_perforacion AS mq ON (mq.id = pz.id_maquina)
WHERE p.id = 2 GROUP BY mq.nombre,sa.nombre)z
You can modify this with the help of order by or having clauses inside window function as you want. I tried this with my own data set. Hope this helps.

Left join not returning record with null

Here's the structure of my database (used to collect info from a survey):
question_responses->answer_choices->subquestions->questions->survey
| ^
V |
submissions->response_group<----------------------------survey_deployment
where A->B means A has the PK of B
So, I want to get the responses of a particular user; let's say that his submission pk is 1. I had written the query
select question_responses.answer_text
from submissions join question_responses on (question_responses.submission_pk = submission.pk)
join answer_choices on (question_responses.answer_choices_pk = answer_choices.pk)
join subquestions on (answer_choices.subquestions_pk = subquestions.pk)
right join questions on (subquestions.questions_pk = questions.pk)
where submissions.pk = 1
order by questions.order
It is possible to not answer questions. In such a case, there is no question_responses.pk recorded. I would still like to be able to account for skipping, so I need this record to be returned, even if there is no response. I thought that the right join would have accounted for this record, but apparently not.
Any help is greatly appreciated.
Because you have submissions.pk = 1 in the where clause this effectively turns your outer join into an inner join, since any missing submission will have a pk of null. and null = 1 is not true.
You could rewrite your query using a LEFT JOIN, and selecting from questions:
select question_responses.answer_text
from questions
left join (subquestions
inner join answer_choices
on answer_choices.subquestions_pk = subquestions.pk
inner join question_responses
on question_responses.answer_choices_pk = answer_choices.pk
inner join submissions
on question_responses.submission_pk = submission.pk)
on subquestions.questions_pk = questions.pk
and submissions.pk = 1
order by questions.order;
This is similar to doing something like:
select subquery.answer_text
from questions
left join
( select question_responses.answer_text, subquestions.questions_pk
from subquestions
inner join answer_choices
on answer_choices.subquestions_pk = subquestions.pk
inner join question_responses
on question_responses.answer_choices_pk = answer_choices.pk
inner join submissions
on question_responses.submission_pk = submission.pk
where submissions.pk = 1
) subquery
on subquery.questions_pk = questions.pk
order by questions.order;
but depending on your dbms the former may perform better as it has no derived tables.
Check out this, does it help?
SELECT question_responses.answer_text
FROM questions LEFT JOIN subquestions on (subquestions.questions_pk = questions.pk)
LEFT JOIN answer_choices on (answer_choices.subquestions_pk = subquestions.pk)
LEFT JOIN question_responses on (question_responses.answer_choices_pk = answer_choices.pk)
LEFT JOIN submissions on (question_responses.submission_pk = submission.pk)
WHERE submissions.pk = 1
ORDER BY questions.order

Avoiding NULL records on this LEFT JOIN

The query below works - EXCEPT - it is returning NULL values for vehicle_id. I do not want any records that have NULL for vehicle_id.
Since vehicle_id is tied to fund_series, this is complicated to me.
When I had the vehicle_id conditions underneath the WHERE, the query was not working. Any SQL geniuses that can help?
I put the MIN() aggregate functions in there just so I could get the GROUP BY to work.
SELECT DISTINCT
MIN(ml.pretty_file_name),
ml.filename,
MIN(ml.issued_date),
MIN(mr.rule_name),
MIN(mlob.line_of_business_name),
MIN(mt.media_type_name),
MAX(v.vehicle_name)
FROM Media_Live ml
JOIN Media_Type mt
ON mt.media_type_id = ml.media_type_id
JOIN Media_Rule mr
ON mr.rule_id = ml.rule_id
JOIN Media_Line_Of_Business mlob
ON mlob.line_of_business_id = ml.line_of_business_id
LEFT JOIN Fund_Class_Media fcm
ON fcm.media_id=ml.media_id
LEFT JOIN Fund_Class_Live fc
ON fc.fund_class_id = fcm.fund_class_id
LEFT JOIN Fund_Series fs
ON fs.fund_series_id = fc.fund_series_id
LEFT JOIN Vehicle AS v
ON v.vehicle_id=fs.vehicle_id AND /*THIS IS WHERE IM GETTING NULLS*/
(
v.vehicle_id = 1
OR v.vehicle_id = 2
OR v.vehicle_id = 5
)
LEFT JOIN Media_Media_Tag AS mmt ON mmt.media_id=ml.media_id
LEFT JOIN Media_Tag AS mtag ON mtag.tag_id=mmt.tag_id
WHERE
(/*people can search with terms for fc*/
--fc.fund_class_id LIKE '%'+replace(?,' ','%')+'%'
)
(
mt.media_type_id = 33
OR mt.media_type_id = 1
OR mt.media_type_id = 12
)
AND
(
mr.rule_id = 3
OR mr.rule_id = 9
)
AND
(
mtag.tag_name != 'exclude_web_lit_center'
)
GROUP BY ml.filename
This is what a left join does, allow nulls. Just take out the left join part making it an inner join.
JOIN Vehicle AS v ON v.vehicle_id=fs.vehicle_id AND v.vehicle_id IN (1,2,5)
You cold also do this, but I don't see why you would:
LEFT JOIN Vehicle AS v ON v.vehicle_id=fs.vehicle_id AND ISNULL(v.vehicle_id,0) IN (1,2,5)
In the WHERE clause, add:
AND v.Vehicl_Id IS NOT NULL
That should do it.

Using left join and inner join in the same query

Below is my query using a left join that works as expected. What I want to do is add another table filter this query ever further but having trouble doing so. I will call this new table table_3 and want to add where table_3.rwykey = runways_updatable.rwykey. Any help would be very much appreciated.
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
'*************EDIT To CLARIFY *****************
Here is the other statement that inner join i would like to use and I would like to combine these 2 statements.
SELECT *
FROM RUNWAYS_UPDATABLE A, RUNWAYS_TABLE B
WHERE A.RWYKEY = B.RWYKEY
'***What I have so far as advice taken below, but getting syntax error
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*, AIRPORT_RUNWAYS_SELECTED.*
FROM RUNWAYS_UPDATABLE
INNER JOIN AIRPORT_RUNWAYS_SELECTED
ON RUNWAYS_UPDATABLE.RWYKEY = AIRPORT_RUNWAYS_SELECTED.RWYKEY
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
NOTE: If i comment out the inner join and leave the left join or vice versa, it works but when I have both of joins in the query, thats when im getting the syntax error.
I always come across this question when searching for how to make LEFT JOIN depend on a further INNER JOIN. Here is an example for what I am searching when I am searching for "using LEFT JOIN and INNER JOIN in the same query":
SELECT *
FROM foo f1
LEFT JOIN (bar b1
INNER JOIN baz b2 ON b2.id = b1.baz_id
) ON
b1.id = f1.bar_id
In this example, b1 will only be included if b2 is also found.
Remember that filtering a right-side table in left join should be done in join itself.
select *
from table1
left join table2
on table1.FK_table2 = table2.id
and table2.class = 'HIGH'
I finally figured it out. Thanks for all your help!!!
SELECT * FROM
(AIRPORT_RUNWAYS_SELECTED
INNER JOIN RUNWAYS_UPDATABLE
ON AIRPORT_RUNWAYS_SELECTED.RWYKEY = RUNWAYS_UPDATABLE.RWYKEY)
LEFT JOIN TURN_UPDATABLE ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
Add your INNER_JOIN before your LEFT JOIN:
SELECT *
FROM runways_updatable ru
INNER JOIN table_3 t3 ON ru.rwykey = t3.rwykey
LEFT JOIN turn_updatable tu
ON ru.rwykey = tu.rwykey
AND (tu.airline_code IS NULL OR tu.airline_code = '' OR tu.airline_code = '')
WHERE ru.icao = 'ICAO'
AND (ru.tora > 4000 OR ru.lda > 0)
If you LEFT JOIN before your INNER JOIN, then you will not get results from table_3 if there is no matching row in turn_updatable. It's possible this is what you want, but since your join condition for table_3 only references runways_updatable, I would assume that you want a result from table_3, even if there isn't a matching row in turn_updatable.
EDIT:
As #NikolaMarkovinović pointed out, you should filter your LEFT JOIN in the join condition itself, as you see above. Otherwise, you will not get results from the left-side table (runways_updatable) if that condition isn't met in the right-side table (turn_updatable).
EDIT 2: OP mentioned this is actually Access, and not MySQL
In Access, perhaps it's a difference in the table aliases. Try this instead:
SELECT [ru].*, [tu].*, [ars].*
FROM [runways_updatable] AS [ru]
INNER JOIN [airport_runways_selected] AS [ars] ON [ru].rwykey = [ars].rwykey
LEFT JOIN [turn_updatable] AS [tu]
ON [ru].rwykey = [tu].rwykey
AND ([tu].airline_code IS NULL OR [tu].airline_code = '' OR [tu].airline_code = '')
WHERE [ru].icao = 'ICAO'
AND ([ru].tora > 4000 OR [ru].lda > 0)
If it is just an inner join that you want to add, then do this. You can add as many joins as you want in the same query. Please update your answer if this is not what you want, though
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
INNER JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
I am not really sure what you want. But maybe something like this:
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*
FROM RUNWAYS_UPDATABLE
JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
For Postgres, query planner does not guarantee order of execution of join. To Guarantee one can use #Gajus solution but the problem arises if there are Where condition for inner join table's column(s). Either one would to require to carefully add the where clauses in the respective Join condition or otherwise it is better to use subquery the inner join part, and left join the output.