How do I join these two selects, what am I doing wrong? - sql

Ok the task at hand is
Obtain the sum of the prizes that have been distributed the exhibitions, until August 31, 2017, for collections and photos. We assume that the awards have never been deserted.
And my code is more or less this
select t1.exhibitions, t2.exhibitions
from (
select exhibitions.premioc
from exhibitions
where EXISTS (select exhibitions.priceC
from exhibitions
join presentCo on exhibitions.id_e = presentCo.id_e
where presentaco.premiada > 0
group by exhibitions.priceC
)
) as t1
left outer join (select exhibitions
from exhibitions
where EXISTS (select exhibitions.priceF
from exhibitions
join presentFo on exhibitions.id_e = presentFo.id_e
where presentafo.preiceC > 0
group by exhibitions.priceF
)
) as "t2"
on t1.exhibitions= t2.exhibitions;
My problem is that I kinda don't know enough of the syntax in SQL and fumbling last minute before delivery (school assignment). I have tried to search and get things to work but I have no idea what I am doing wrong with this part. Any pointer would be awesome. Thank you very much for anything
Edit: being way to late in the night when I posted it I never mentioned the real problem, I get SQL Error: ORA-00933: SQL command not properly ended and don't really get why.

for:
sum of all prizes
distributed at exhibitions, until August 31, 2017
a query would look something like this:
select sum(prize_money)
from exhibitions
where exhibition_date < '2017-09-01'
I suspect the answer is much simpler then you first thought
----
Your existing query has several problems that I an see:
select t1.exhibitions -- this column is not returned by subquery t1
, t2.exhibitions
from (
select exhibitions.premioc -- only this column is returned by subquery t1
from exhibitions
where EXISTS -- when using EXISTS you need a "correlation" inside the where clause of the subquery
(select exhibitions.priceC
from exhibitions
join presentCo on exhibitions.id_e = presentCo.id_e
where presentaco.premiada > 0 -- there is NO "correlation" here
group by exhibitions.priceC
)
) as t1
left outer join (select exhibitions
from exhibitions
where EXISTS ( -- when using EXISTS you need a "correlation" inside the where clause of the subquery
select exhibitions.priceF
from exhibitions
join presentFo on exhibitions.id_e = presentFo.id_e
where presentafo.preiceC > 0 -- there is NO "correlation" here
group by exhibitions.priceF
)
) as "t2"
on t1.exhibitions= t2.exhibitions;
----
I suggest you need to start new, maybe with this as a starting point?
SELECT
exhibitions.id_e
, COALESCE(c.prize_c, 0) prize_c
, COALESCE(f.prize_f, 0) prize_f
FROM exhibitions
LEFT JOIN (
SELECT
presentCo.id_e
, SUM(prize) prize_c
FROM presentCo
GROUP BY
presentCo.id_e
) AS c ON exhibitions.id_e = c.id_e
LEFT JOIN (
SELECT
presentFo.id_e
, SUM(proze) price_f
FROM presentFo
GROUP BY
presentFo.id_e
) AS f ON exhibitions.id_e = presentFo.id_e
But I shall not attempt further suggestions unless I see "sample data" (for each table) and, the "expected result"

Related

Check if a combination of fields already exists in the table

My weakest area of SQL are self JOINS, currently struggling with an issue.
I need to find the latest entry in a table, I'm using a WHERE DATEFIELD IN (SELECT MAX(DATEFIELD) FROM TABLE) to do this. I then need to establish if 3 columns from that already exist in the same TABLE.
My latest attempt looks like this -
SELECT * FROM PART_TABLE
WHERE NOT EXISTS
(
SELECT
t1.DATEFIELD
t1.CODE1
t1.CODE2
t1.CODE3
FROM PART_TABLE t1
INNER JOIN PART_TABLE t2 ON t1.UNIQUE = t2.UNQIUE
)
WHERE t1.DATEFIELD IN
(
SELECT MAX(DATEFIELD)
FROM PARTTABLE
)
)
I think part of the issue is that I can't exclude the unique row from t1 when checking in t2 using this method.
Using MSSQL 2014.
The following query will return the latest record from your table and a bit flag whether a duplicate tuple {Code1, Code2, Code3} exists in it under a different identifier:
select top (1) p.*,
case when exists (
select 0 from dbo.Part_Table t where t.Unique != p.Unique
and t.Code1 = p.Code1 and t.Code2 = p.Code2 and t.Code3 = p.Code3
) then 1
else 0 end as [IsDuplicateExists]
from dbo.Part_Table p
order by p.DateField desc;
You can use this example as a template to address your specific needs, which unfortunately aren't immediately apparent from your explanation.

How to join 100 random rows from table 1 multiple other tables in oracle

I have scrapped my previous question as I did not do a good job explaining. Maybe this will be simpler.
I have the following query.
Select * from comp_eval_hdr, comp_eval_pi_xref, core_pi, comp_eval_dtl
where comp_eval_hdr.START_DATE between TO_DATE('01-JAN-16' , 'DD-MON-YY')
and TO_DATE('12-DEC-17' , 'DD-MON-YY')
and comp_eval_hdr.COMP_EVAL_ID = comp_eval_dtl.COMP_EVAL_ID
and comp_eval_hdr.COMP_EVAL_ID = comp_eval_pi_xref.COMP_EVAL_ID
and core_pi.PI_ID = comp_eval_pi_xref.PI_ID
and core_pi.PROGRAM_CODE = 'PS'
Now if I only want a random 100 rows from the comp_eval_hdr table to join with the other tables how would I go about it? If it makes it easier you can disregard the comp_eval_dtl table.
I think you are pretty much there. You just need subqueries, table aliases, and JOIN conditions:
SELECT . . .
FROM (SELECT a.*
FROM (SELECT a.*
FROM a
WHERE a.START_DATE BEWTWEEN DATE '2016-01-01' AND DATE '2017-12-12'
ORDER BY DBMS_RANDOM.VALUE
) a
WHERE ROWNUM <= 100
) a JOIN
mapping m
ON a.? = m.? JOIN
b
ON m.? = b.?;
The ? is just a placeholder for the join columns.
It's a bit of a stretch to know what you want with the question as written but here's my attempt.
WITH rand_list AS
(SELECT * FROM comp_eval_hdr
WHERE comp_eval_hdr.START_DATE BEWTWEEN TO_DATE('01-JAN-16' , 'DD-MON-YY') AND TO_DATE('12-DEC-17' , 'DD-MON-YY')
ORDER BY DBMS_RANDOM.VALUE)
first_100 AS
(SELECT *
FROM rand_list
WHERE ROWNUM <=100)
SELECT md.col_1, t3.col_a
FROM first_100 md
INNER JOIN
table2 t2 ON md.id_column = t2.fk_comp_eval_hdr_id
INNER JOIN
table3 t3 ON t3.id_column = t2.fk_table3_id
You haven't given any indication how they join or the table names and obviously I haven't run this against any mock tables.
You've got a list of randomised records with RAND_LIST which you could, if you wanted, combine with the FIRST_100 query (your choice).
The main query then just joins that through your mapping table (T2) to your 'multiples' table (T3).
how does table 2 look like?...Let me put one example as person table and order table?
select * from (
select * from person ps , order order where ps.city = 'mumbai' and ps.id = order.purchasedby ) porder where porder.rownum <= 100
I did not tested it but it will look something like this.

SQL Inner Join and nearest row to date

I dont't get it. I changed some of the code. In the WPLEVENT Table are a lot of Events per person. In the Persab-Table are the Persons with their History. Now I need the from the Persab Table just that row wich matches the persab.gltab Date nearest to the WPLEVENT.vdat Date. So all rows from the WPLEVENT, but just the one matching row from the PERSAB-Table.
SELECT
persab.name,
persab.vorname,
vdat,
eventstart,
persab.rc1,
persab.rc2
FROM wplevent
INNER JOIN
persab ON WPLEVENT.PersID = persab.PRIMKEY
INNER JOIN
(SELECT TOP 1 persab.rc1
FROM PERSAB
WHERE persab.gltab <= getdate() --/ Should be wplevent.vdat instead of getdate()
) NewTable ON wplevent.persid = persab.primkey
WHERE
persid ='100458'
ORDER BY vdat DESC
Need to use the MAX() function with the proper syntax by supplying an expression like MAX(persab.rc1). Also need to use GROUP BY for the second column rc2 in the subquery (although it looks like you do not need it). Finally you are missing the ON clause for the final INNER JOIN. I can update the answer to fix the query if you provide that information.
SELECT
Z1PERS.NAME
, Z1PERS.VORNAME
, WPLEVENT.VDat
, WPLEVENT.EventStart
, WPLEVENT.EventStop
, WPLEVENT.PEPGROUP
, Z1SGRP.TXXT
, PERSAB.GLTAB
, Z1PERS.PRIMKEY AS Expr1
, PERSAB.PRIMKEY
FROM
Z1PERS
INNER JOIN
WPLEVENT ON Z1PERS.PRIMKEY = WPLEVENT.PersID
INNER JOIN
Z1SGRP ON WPLEVENT.PEPGROUP = Z1SGRP.GRUPPE
INNER JOIN
(
SELECT MAX(Persab.rc1) --Fixed MAX expression
, persab.rc2
FROM
persab
GROUP BY
persab.rc2 --Need to group on rc2 if you want that column in the query otherwise remove this AND the rc2 column from select list
WHERE
WPLEVENT.PersID = PERSAB.PRIMKEY
AND WPLEVENT.VDat <= PERSAB.GLTAB
) --Missing ON clause for the INNER JOIN here
WHERE z1pers.vorname = 'henning'

Why do I get ORA-00907 in my SQL query?

I have this SQL query which a partner has done for a little project at university (this is the first time we use SQL), but we get the ora-00907 error and both of us don't know why.
I have checked the parenthesis and they seem to be ok, so the problem must be another.
select
persona.nombre,
anyo,
t2.total
from persona join
(
select
t1.idPersona,
count(produccion.anyo) as total,
anyo
from
(
select *
from produccion
join pelicula
on produccion.id = pelicula.id
) as pel
join
(
select *
from participa
where idPapel = 8
) as t1
on t1.idProduccion = pel.id
)
group by t1.idPersona
) as t2
on persona.id = t2.idPersona
where t2.total > 2
order by t2.total desc;
You are selecting * and doing group by on one column which is creating problem. Either you select only respective column under group by condition OR you remove group by.
select *
from (produccion join pelicula on produccion.id=pelicula.id) as pel
join
(select *
from participa
where idPapel=8) as t1
on t1.idProduccion=pel.id)
group by t1.idPersona
Above code section is unallowed use of group by.
If group by is so much needed, i would suggest you to use it later on in the end. Another option is to use analytical function and filter out rest un-wanted records in upper nesting of query which you already have.
You have lots of nested views, which makes your query rather hard to debug. You have lots of brackets, which need to match.
Anyway this is wrong: select t1.idPersona, count(produccion.anyo) as total, anyo. You'll need to include anyo in the GROUP BY clause, which will probably change the result set you want.
select persona.nombre,
t2.anyo,
t2.total
from persona join
(select t1.idPersona,
count(produccion.anyo) as total,
anyo
from (select *
from produccion
join pelicula
on produccion.id=pelicula.id) pel
join
(select *
from participa
where idPapel=8) t1
on t1.idProduccion=pel.id
group by t1.idPersona, t1.anyo) t2
on persona.id=t2.idPersona
where t2.total>2
order by t2.total desc;
I think your query can be simplified/corrected like this:
select persona.nombre,
anyo,
t2.total
from persona
join (
select par.idPersona,
count(produccion.anyo) as total,
anyo
from produccion
join pelicula
on produccion.id = pelicula.id
left join participa par
on par.idProduccion = pelicula.id -- or produccion.id,
-- this was also an error in the original query,
-- since the subquery selected both
and par.idPapel = 8
group by t1.idPersona
, anyo -- Was missing, but it also doesn't make sense, as this is what you count, so you'll just get 1's here. What do you want with this?
) as t2
on persona.id = t2.idPersona
where t2.total > 2
order by t2.total desc;

DB2 Alternate to EXISTS Function

I have the below query in my application which was running on DB2:
SELECT COD.POST_CD,CLS.CLASS,COD2.STATUS_CD
FROM DC01.POSTAL_CODES COD
INNER JOIN DC02.STATUS_CODES COD2
ON COD.ORDER=COD2.ORDER
INNER JOIN DC02.VALID_ORDERS ORD
ON ORD.ORDER=COD.ORDER
WHERE
(
( EXISTS (SELECT 1 FROM DC00.PROCESS_ORDER PRD
WHERE PRD.ORDER=COD.ORDER
AND PRD.IDNUM=COD.IDNUM
)
) OR
( EXISTS (SELECT 1 FROM DC00.PENDING_ORDER PND
WHERE PND.ORDER=COD.ORDER
AND PND.IDNUM=COD.IDNUM
)
)
)
AND EXISTS (SELECT 1 FROM DC00.CUSTOM_ORDER CRD
WHERE CRD.ORDER=COD.ORDER
)
;
When we changed to UDB (LUW v9.5) we are getting the below warning:
IWAQ0003W SQL warnings were found
SQLState=01602 Performance of this complex query might be sub-optimal.
Reason code: "3".. SQLCODE=437, SQLSTATE=01602, DRIVER=4.13.111
I know this warning is due to the EXISTS () OR EXISTS statements. But I am not sure any other way I can write this query to replace. If it is AND, I could have made an INNER JOIN, but I am not able to change this condition as it is OR. Can any one suggest better way to replace these EXISTS Statements?
SELECT COD.POST_CD,CLS.CLASS,COD2.STATUS_CD
FROM DC01.POSTAL_CODES COD
INNER JOIN DC02.STATUS_CODES COD2
ON COD.ORDER=COD2.ORDER
INNER JOIN DC02.VALID_ORDERS ORD
ON ORD.ORDER=COD.ORDER
WHERE
(
EXISTS SELECT 1 FROM
(SELECT ORDER,IDNUM FROM DC00.PROCESS_ORDER PRD UNION
SELECT ORDER,IDNUM FROM DC00.PENDING_ORDER PND) PD
WHERE PD.ORDER=COD.ORDER
AND PD.IDNUM=COD.IDNUM
)
AND EXISTS (SELECT 1 FROM DC00.CUSTOM_ORDER CRD
WHERE CRD.ORDER=COD.ORDER
)
;