Cross apply in MY SQL - mysql

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

Related

how can i solve this question? using self inner join and some conditions?

the first picture is the table . second picture is the expected output.
conditions are 1. refids should be same. 2. for all the same ref ids (a.start,a.end &b.start,b.end) in the current and previous row. 3. should calculate the time difference which is greater than or equal to one day.
You want pairs of rows that match certain condition. You can perform a join to identify the pairs.
You don't say which version of MySQL you are using but in MySQL 8.x you can do:
with
x as (
select a.id
from my_table a
join my_table b on b.id = a.id + 1
and b.refid = a.refid
and (a.detail = 'a.end' and b.detail = 'a.start'
or a.detail = 'b.end' and b.detail = 'b.start')
)
select t.*
from my_table t
join x on t.id = x.id or t.id = x.id + 1
For MySQL 5.x you can do:
select t.*
from my_table t
join (
select a.id
from my_table a
join my_table b on b.id = a.id + 1
and b.refid = a.refid
and (a.detail = 'a.end' and b.detail = 'a.start'
or a.detail = 'b.end' and b.detail = 'b.start')
) x on t.id = x.id or t.id = x.id + 1

Using an Case function in a MySQL SELECT query then select

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

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;

Can you Divide 2 completely different query results into 1 result

I'm trying to divide the numeric results from 2 pretty different queries.
The end result should be Query 1 DIVIDED BY Query 2
Query 1 =
SELECT COUNT(DISTINCT(table1.ID)) AS count_1
FROM table1
INNER JOIN op
INNER JOIN Org
ON table1.EID = op.id
AND Op.OrgID = Org.ID
WHERE table1.TitleID = 123
AND op.BrandID = 1
AND op.Start <= NOW() AND op.End >= NOW();
Query 2 =
SELECT COUNT(DISTINCT user.id) AS count_2
FROM table1 INNER JOIN user INNER JOIN ur
ON table1.EID = user.id AND ur.userID = user.id
WHERE
user.BrandID = 1
AND table1.TitleID = 123
AND ur.role = 0
AND user.Inactive = 0;
Sure! You can use subselects to achieve this, though it will be pretty verbose!
SELECT
(
SELECT COUNT(DISTINCT(table1.ID)) AS count_1
FROM table1
INNER JOIN op
INNER JOIN Org
ON table1.EID = op.id
AND Op.OrgID = Org.ID
WHERE table1.TitleID = 123
AND op.BrandID = 1
AND op.Start <= NOW() AND op.End >= NOW()
) / (
SELECT COUNT(DISTINCT user.id) AS count_2
FROM table1 INNER JOIN user INNER JOIN ur
ON table1.EID = user.id AND ur.userID = user.id
WHERE
user.BrandID = 1
AND table1.TitleID = 123
AND ur.role = 0
AND user.Inactive = 0
);
Format however it feels the least ugly to you.
Use sub queries like this:
SELECT Q1.count_1 / Q2.Count_2
FROM
( ... Query1 ...) AS Q1
JOIN
( ... Query2 ...) AS Q2
ON 1=1
Replace Query1 and Query2 as your code.
Like this:
SELECT count_1 / count_2
FROM (SELECT COUNT(*) count_1 FROM foo) f
JOIN (SELECT COUNT(*) count_2 FROM bar) b ON 1=1;
http://sqlfiddle.com/#!2/c215e/1

Difficult MySQL Statement

I've got this query but the result is wrong.
How can I use the min() statement and the Group by Statement so that I will get for each AthletenID the lowest DiszOrder?
Select
ar_Leistungen.`AthletenID`,
ar_Leistungen.`Leistung`,
ar_Leistungen.`Disziplin`,
ar_Leistungen.`Klasse`,
min(ar_Leistungen.`DiszOrder`),
ar_Athleten.`Vorname`,
ar_Athleten.`Jahrgang`,
ar_Wettkampf.`Wettkampfdatum`
from
ar_Leistungen,
ar_Athleten,
ar_Wettkampf
Where
ar_Athleten.ID = ar_Leistungen.AthletenID and
ar_Leistungen.WettkampfID = ar_Wettkampf.ID and
ar_Leistungen.`Disziplin` = '100' and
ar_Leistungen.`Leistung` > 0 and
(ar_Athleten.`Jahrgang` = '1995' or ar_Athleten.`Jahrgang` = '1994') and
ar_Wettkampf.`Wettkampfdatum` LIKE '%2013%'
Group By
AthletenID
Order by
DiszOrder Desc
Limit
0, 100
You can have a subquery which separately gets the lowest DiszOrder for each AthletenID and join it with the other table so you can freely get the other value of the columns.
SELECT a.AthletenID,
a.Leistung,
a.Disziplin,
ar_Leistungen.Klasse,
a.DiszOrder),
b.Vorname,
b.Jahrgang,
c.Wettkampfdatum
FROM ar_Leistungen a
INNER JOIN ar_Athleten b
ON b.ID = a.AthletenID
INNER JOIN ar_Wettkampf c
ON a.WettkampfID = c.ID
INNER JOIN
(
SELECT AthletenID, MIN(DiszOrder) DiszOrder
FROM ar_Leistungen
GROUP BY AthletenID
) d ON a.AthletenID = d.AthletenID AND
a.DiszOrder = d.DiszOrder
WHERE a.Disziplin = '100' AND
a.Leistung > 0 AND
(b.Jahrgang IN ('1995', '1994'))