Using an Case function in a MySQL SELECT query then select - mysql

I am trying to use an Case statement in a MySQL select query.
I am getting an error (Subquery returns more than 1 row)
SELECT mony.come,mony.go,mony.details,mony.id_bill,
(
case mony.details
when 'collect' then (SELECT collect_from_customer.num FROM collect_from_customer INNER JOIN mony ON mony.id_bill = collect_from_customer.id WHERE collect_from_customer.id=mony.id_bill )
when 'pay_to_cust' then (SELECT pay_to_customer.num FROM pay_to_customer INNER JOIN mony ON mony.id_bill = pay_to_customer.id WHERE pay_to_customer.id=mony.id_bill )
end
) as idd
,mony.date FROM mony
please help me

thanks i found solution
SELECT m.come,m.go,m.details,m.id_bill,
(
case m.details
when 'collect' then (SELECT collect_from_customer.num FROM collect_from_customer INNER JOIN mony m1 ON m1.id_bill = collect_from_customer.id WHERE collect_from_customer.id=m.id_bill LIMIT 1 )
when 'pay_to_cust' then (SELECT pay_to_customer.num FROM pay_to_customer INNER JOIN mony m1 ON m1.id_bill = pay_to_customer.id WHERE pay_to_customer.id=m.id_bill LIMIT 1 )
end
) as idd
,m.date FROM mony m

Related

Unknown column in 'IN/ALL/ANY subquery'

Why am I getting this error? Error is showing up in the OR clause, but I'm selecting gl_ID inside the SELECT statement.
; DECLARE v_firstDate DATETIME
SET #p_ID = 368
SELECT SUBDATE(NOW(), 1) INTO v_firstDate;
SELECT t_ID, t_firstName, t_lastName
FROM t_table
WHERE
((#p_ID IN (
SELECT tt_ID
FROM tt_tableTwo
INNER JOIN st_stats ON (st_ID = tt_ID)
INNER JOIN da_data ON (da_ID = st_ID AND da_name IN ("allCompanies", "allglobals"))
)
))
OR
(
(gl_ID IN ( //problem is here
SELECT gl_ID
FROM gl_globals
INNER JOIN tr_transport ON (tr_id = gl_caseID AND tr_idOther = #p_ID)
INNER JOIN co_countries ON (co_ID = gl_ID AND co_ID = #p_ID)
)
)
)
Error message:
Unknown column 'gl_ID' in 'IN/ALL/ANY subquery'
Should I be using an AS or a HAVING?
gl_ID is not accessible in the OR clause because it doesn't exist in t_table. An inner join under the first FROM clause solves the problem.
; DECLARE v_firstDate DATETIME
SET #p_ID = 368
SELECT SUBDATE(NOW(), 1) INTO v_firstDate;
SELECT t_ID, t_firstName, t_lastName
FROM t_table
INNER JOIN gl_globals ON (t_ID = gl_ID) // fix
WHERE
((#p_ID IN (
SELECT tt_ID
FROM tt_tableTwo
INNER JOIN st_stats ON (st_ID = tt_ID)
INNER JOIN da_data ON (da_ID = st_ID AND da_name IN ("allCompanies", "allglobals"))
)
))
OR
(
(gl_ID IN (
SELECT gl_ID
FROM gl_globals
INNER JOIN tr_transport ON (tr_id = gl_caseID AND tr_idOther = #p_ID)
INNER JOIN co_countries ON (co_ID = gl_ID AND co_ID = #p_ID)
)
)
)

Cross apply in MY SQL

Am trying to convert this Sql server script to mysql.
SELECT A.*
FROM TableA A
CROSS APPLY
(
SELECT TOP 1 UID
FROM TableB
WHERE BetID = A.BetID
AND BETCODE = A.BETCODE
ORDER BY CASE WHEN InfoCode > '' THEN 0 ELSE 1 END,UID
)Z
WHERE Z.UID = A.UID
Can please advise as how, I know I can change CROSS JOIN and Limit 1 but still it fails
in you can't use TOP but use limit so you could try and in MySql the scope for subquery table is differente respect to SQL_SERVER so you must buil the join inside the subquery
SELECT A.*
FROM TableA A
CROSS JOIN
( SELECT UID
FROM TableB
INNER JOIN TABLEA A ON BetID = A.BetID
AND BETCODE = A.BETCODE
ORDER BY CASE WHEN InfoCode > '' THEN 0 ELSE 1 END,UID
LIMIT 1
) Z
WHERE Z.UID = A.UID
or a cross join with a single result could be also translate as an inner join
SELECT A.*
FROM TableA A
INNER JOIN
( SELECT UID
FROM TableB
INNER JOIN TABLEA A ON BetID = A.BetID
AND BETCODE = A.BETCODE
ORDER BY CASE WHEN InfoCode > '' THEN 0 ELSE 1 END,UID
LIMIT 1
) Z ON Z.UID = A.UID

Mysql subquery in a view very slow

I'm trying get last result from a table using the data_coleta (DATE) and servico_id as base. The query is working but is very slow. How can I optimize?
select t1.* from
amostra_ensaio_full t1
where
t1.cliente_id = 6 and t1.tipo_id <> 1
and t1.data_coleta = (SELECT max(s1.data_coleta) from amostra_ensaio_full s1 where t1.cliente_id = s1.cliente_id and s1.tipo_id <> 1 and s1.tipo_id = t1.tipo_id)
and t1.servico_id = (SELECT max(s2.servico_id) from amostra_ensaio_full s2 where t1.cliente_id = s2.cliente_id and s2.tipo_id <> 1 and s2.tipo_id = t1.tipo_id)
GROUP by t1.cliente_id , t1.tipo_id
You can probably speed up this query using indexes.
The query is:
select t1.*
from amostra_ensaio_full t1
where t1.cliente_id = 6 and t1.tipo_id <> 1 and
t1.data_coleta = (SELECT max(s1.data_coleta)
from amostra_ensaio_full s1
where t1.cliente_id = s1.cliente_id and
s1.tipo_id <> 1 and
s1.tipo_id = t1.tipo_id
) and
t1.servico_id = (SELECT max(s2.servico_id)
from amostra_ensaio_full s2
where t1.cliente_id = s2.cliente_id and
s2.tipo_id <> 1 and
s2.tipo_id = t1.tipo_id
)
GROUP by t1.cliente_id , t1.tipo_id;
You want the following index for the query: amostra_ensaio_full(cliente_id, tipo_id, servico_id).
The condition tipo_id <> 1 is unnecessary in the subquery, but it causes no harm.
Tks Gordon but the query still slow. Maybe I found the answer searching more.
SELECT a.*
FROM amostra_ensaio_full a
INNER JOIN
(
SELECT MAX(data_coleta) maxDate , tipo_id, cliente_id
FROM amostra_ensaio_full
GROUP BY cliente_id, tipo_id
) b ON a.cliente_id = b.cliente_id and a.tipo_id = b.tipo_id and b.maxDate = a.data_coleta
GROUP by a.cliente_id ,a.tipo_id

Getting Events Between Two Dates using MySql

I have this table: http://sqlfiddle.com/#!2/b4060/2
I then created two views as follow:
-- stack 1: hire
create view HS1H as
select a.* , min(a.`Effective_Date`)
from `Table1` a
left join `Table1` b on a.`Employee_ID` = b.`Employee_ID`
and a.`Effective_Date` > b.`Effective_Date`
where a.`Event_Type` = "1_Hire"
group by a.`Employee_ID`;
select * from `hs1h`;
-- stack 1: termination
create view HS1T as
select a.* , min(a.`Effective_Date`)
from `Table1` a
left join `Table1` b on a.`Employee_ID` = b.`Employee_ID`
and a.`Effective_Date` > b.`Effective_Date`
where a.`Event_Type` = "5_Term"
group by a.`Employee_ID`;
select * from `hs1t`;
I want to get the events that happen between first Hire date and first Term date. I used the qry below but returned no results:
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` between b.`Effective_Date` and c.`Effective_Date`;
I am not sure what went wrong. I was able run the following two qrys. One returned the events after first hire date, and the other returned the events before first term date. But when I combine them like the one above, it didn't work.
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` > b.`Effective_Date`;
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` < c.`Effective_Date`;
SELECT *
FROM table1
WHERE `effective date`
BETWEEN (select MIN(`effective date`) from `Table1` WHERE `event type` = '1_Hire')
AND
(select MIN(`effective date`) FROM table1 WHERE `event type` = '5_Term')
For the 2nd or 3rd 'hire', things get a little more complicated, but something like this should work...
SELECT a.*
FROM TH_Sample_Data a
JOIN (
SELECT x.*
, MIN(y.effective_date) end
, #i := #i+1 rank
FROM TH_Sample_Data x
JOIN TH_Sample_Data y
ON y.effective_date >= x.effective_date
AND y.event_type = '5_Term'
, (SELECT #i:=1) vars
WHERE x.event_type = '1_Hire'
GROUP
BY x.id
) b
ON a.effective_date BETWEEN b.effective_date and b.end
WHERE b.rank = 2;

sql server cross join

I have the following query:
select
tt.ItemOrder, tt.DisplayVal as Task, tt.Responsible as ResParty,
tt.DaysDue,
ActualDate = (select convert(varchar(10), cnfmdate, 101) from ProSer where PId = #PID), PDate = #PDate
from
tblTimeline tt
where
tt.ID = 1
What I need to do is to put it in a view such that I can call the view simply using the PID.
I came up with the following and used the cross join:
create view view1 as
select
ps.PID, tt.ID, tt.ItemOrder, tt.DisplayVal as Task,
tt.Responsible as ResParty, tt.DaysDue,
ps.cnfmdate As ActualDate, ProgStartDate as ProgramDate
from
tblTimeline tt
cross join
ProSer ps
where
tt.ID = 1 and ps.cancelled = 0
Notice now, I can do the following
select *
from view1
where PID = '34343'
and then I can retrieve it from the view.
Now, I am not sure how to do similiarly with the following in which case I need to put it in a cross join similarly to how I did above.
Notice how actual date is somehat more involved. I need to use the cross table similarly to how I did it above but not as you can see, it is somewhat more involved.
(notice for this part, I will simly join to the view1 that I have above with UNION
select
tt.ItemOrder, tt.DisplayVal as Task, tt.Responsible as ResParty,
ActualDate = (
CASE
WHEN
NOT EXISTS(SELECT * FROM Spls WHERE RequestRcvd = 1 AND PID = #PID)
THEN
'N/A'
WHEN EXISTS (SELECT * FROM spls WHERE RequestRcvd = 1 AND RequestRcvdDate IS NOT NULL)
THEN
(SELECT CONVERT(VARCHAR(10),MAX(RequestRcvdDate),101) from spls WHERE RequestRcvd = 1 AND PID = #PID)
END
)
from
tblTimeline tt
where
tt.ID = 9
I need to know how I can create this in a cross join (which will be inside of a view) such that I can do the following similarly to how I did the above one
select *
from view1
where PID = '34343'
and then I can retrieve it from the view.
There might be a way to simplify the query, but the following should work:
select p.pid, tt.ItemOrder, tt.DisplayVal as Task,
tt.Responsible as ResParty,
ActualDate = (CASE WHEN NOT EXISTS(SELECT * FROM Spls WHERE RequestRcvd = 1 AND spls.PID = p.PID)
THEN 'N/A'
WHEN EXISTS (SELECT * FROM spls WHERE RequestRcvd = 1 AND RequestRcvdDate IS NOT NULL)
THEN (SELECT CONVERT(VARCHAR(10),MAX(RequestRcvdDate),101) from spls WHERE RequestRcvd = 1 AND spls.PID = p.PID)
END)
from tblTimeline tt cross join
poser p
where tt.ID = 9
All I did was add the cross join to poser and replace #PID with p.pid. The results is a subquery that contains a reference to a table at an outer level. Such a subquery is called a correlated subquery.