I want duplicates to be included with my in () statement - mysql

I want to include duplicates into my query. I havent succeeded in changing my "in" statements to "joins".
My expected result is a row count of 115.
My result is a row count of 108.
If i do a "Group by" in my first subquery, i get a row count of 108.
select match_id item_0, item_1, item_2, item_3, item_4, item_5, purchase_log
from player_matches where match_id IN
(select x.match_id from (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id = 1 and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as x
inner join
(select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id
/*this is the statement that needs to be tweaked/changed */
IN (2,12,47,4,99) and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as y on y.match_id=x.match_id and x.team!=y.team)
and hero_id = 1
You can use the opendota inbrowser data-explorer to get a better understanding of my problem.
My subquery (returns 115)
My final Query (returns 108)
How do i get my final query to return 115 row counts?
My query is also really slow, is this because im using "in ()"?

It is because the IN will just check if the value is present. Use INNER JOIN instead:
select a.match_id, a.item_0, a.item_1, a.item_2, a.item_3, a.item_4, a.item_5, a.purchase_log
from player_matches a
INNER JOIN
(
select x.match_id from (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id = 1 and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as x inner join (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id in (2,12,47,4,5) and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as y on y.match_id=x.match_id and x.team!=y.team
) b ON a.match_id = b.match_id
WHERE hero_id = 1
Here's a demo from your original link.

Related

SQL error as a result of rewriting a query using subquery into a query using join

The original query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop.price_type_code,
fop.price_status_code,
fop.offering_id,
(SELECT fop1.price_amount from facility_offering_price fop1
WHERE fop.offering_id = fop1.Offering_Id
AND fop1.price_type_code = 5
AND fop1.price_status_code = 3
) as 'priceAmount'
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It produces a result of one entry.
The result query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop2.price_amount,
fop.price_type_code,
fop.offering_id,
fop2.offering_id
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
inner join
(select
fop1.offering_id,
fop1.price_amount
from facility_offering_price fop1
WHERE fop1.price_type_code = 5
AND fop1.price_status_code = 3
) fop2 on fop.offering_id = fop2.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It's result set is empty. However, an entry is found if I ask for fop1.price_status_code = 1.
Unable to wrap my head around this one I would appreciate your help.
Try using LEFT JOIN instead. The conversion from SELECT a, subquery AS val FROM ... to a join is more accurately reflected that way. The original query would return rows with NULL val when the subquery has no results; your version ends up omitting such rows completely.

mysql combine 2 queries from same table

This is query 1:
SELECT distinct c.chem_gene, m.String_name, m.ScopeNote
FROM mesher m INNER JOIN chem_base c
ON (c.chem_name = m.String_name AND m.ScopeNote <> '' )
where match (c.chem_gene) against('ACTN3, MTHFR' in boolean mode)
group by c.chem_gene, c.chem_name;
which outputs 3 columns in rows like this:
'ACTN3', 'Estradiol', 'The 17-beta-isomer of estradiol...'
This is query 2 (taking the output from column 2, "Estradiol"):
SELECT String10 FROM mesher where String_name = "Estradiol" AND String10 <>'' LIMIT 1;
which outputs a single row in a single column:
'Estrogens'
How can I modify query 1 so that for each row returned the additional query is made against the result in the second column (i.e.'Estradiol') to produce this output:
'ACTN3', 'Estradiol', 'The 17-beta-isomer of estradiol...', 'Estrogens'
If I understand correctly, you can use a correlated subquery:
SELECT c.chem_gene, m.String_name, m.ScopeNote,
(SELECT mm.String10
FROM mesher mm
WHERE mm.String_name = m.String_name AND mm.String10 <> ''
LIMIT 1
)
FROM mesher m INNER JOIN
chem_base c
ON c.chem_name = m.String_name AND m.ScopeNote <> ''
WHERE match(c.chem_gene) against( 'ACTN3, MTHFR' in boolean mode)
GROUP BY c.chem_gene, c.chem_name, m.ScopeNote ;
The select distinct is not necessary.

Adding a WHERE condition on an IF alias in a MySQL query

I'm having trouble adding a condition on aliases is_paid, is_overdue and is_outstanding in the following query:
SELECT r.doc_number,
r.doc_date,
r.due_date,
r.currency,
r.amount,
r.vat,
r.vatammount,
(r.amount + r.vatammount) final_amount,
r.currency,
b.boq_id,
b.boq_comp_id,
b.boq_client_id,
b.boq_agency,
b.boq_date,
b.boq_orders,
b.receivable_id,
c.comp_name,
crm.`cn-name-first`,
crm.`cn-name-last`,
bi.inv_path,
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id) total_amount_received,
IF (r.amount + r.vatammount =
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_paid,
IF (CURRENT_DATE >= r.due_date
AND r.amount + r.vatammount !=
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_overdue,
IF (r.due_date < CURRENT_DATE
AND r.amount + r.vatammount !=
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_outstanding
FROM receivables r
LEFT JOIN boq b ON b.receivable_id = r.id
LEFT JOIN boq_invoices bi ON bi.inv_boq_id = b.boq_id
LEFT JOIN comp_companies c ON c.comp_id = b.boq_comp_id
LEFT JOIN crm_contacts crm ON crm.contact_id = b.boq_client_id
WHERE r.status = 'active'
AND r.doc_type = 'inv'
AND b.boq_status = 'active'
AND is_paid = '1'
ORDER BY r.doc_date DESC LIMIT 10
Is there any way to modify this query and to make it possible to add a condition on those three aliases?
use alias in where condition .. is not allowed . because .is not possibile
the query code is evaluted based on a specified order .. starting from FROM then
WHERE clause and last the SELECT and the column alias so .. when the where is performed the column alias is not available at the query
You could try with an having condition because having work on the result of the query and not on the raw rows value .. (this could have effect on performance ..because all the query is performed and only the result is filtered by having)

Inner join returning more results even after excluding parameters

My actuall query is:
SELECT rrr.extern_OD_id,
rrr.refund_it_amount,
rrr.refund_amount,
rrr.invoice_ref_7,
rrr.invoice_total_amount
FROM
(SELECT return.extern_OD_id,
return.refund_it_amt AS refund_it_Amount,
return.refund_amount,
billing_tbl.invoice_ref_7,
billing_tbl.invoice_total_amount
FROM
(SELECT rrrf.extern_OD_id,
sum(rrrf.refund_it_amt) AS refund_it_amt,
sum(rrrf.refund_amount/100) refund_amount
FROM rrr__refunds_fact rrrf
WHERE rrrf.refund_status = 'completed'
AND rrrf.refund_created_date_key >= '20150401'
AND rrrf.refund_mode IN('CREDIT_CARD',
'CREDIT_EMI',
'DDCHEQUE',
'DEBIT_CARD',
'GIFT_VOUCHER',
'ICICI',
'NETBANKING',
'back_to_source')
AND rrrf.refund_mode NOT IN ('GIFT_Card')
GROUP BY rrrf.extern_OD_id) RETURN
LEFT JOIN
(SELECT invoice_ref_7,
sum(invoice_total_amount) invoice_total_amount
FROM invoice_fact
WHERE invoice_type_key = 'receiv_note'
AND invoice_status_key NOT IN('voided',
'canceled',
'cancelled')
GROUP BY invoice_ref_7) billing_tbl ON RETURN.extern_OD_id =billing_tbl.invoice_ref_7
WHERE RETURN.refund_amount <> billing_tbl.invoice_total_amount
OR billing_tbl.invoice_ref_7 IS NULL) rrr
WHERE rrr.refund_it_amount >0
AND rrr.refund_amount >0
But when I try to join another table and exclude some parameters, it gives me more records than records from table srrr__refunds_fact.
It gives many records from the new joined table i.e. Payment_TBL which are not present in rrr__refunds_fact.
Can you please tell me where I am going wrong.
As per my understanding if the first query is returning n records, after joining the new records should be n or < n
SELECT rrr.extern_OD_id,
rrr.refund_it_amount,
rrr.refund_amount,
rrr.invoice_ref_7,
rrr.invoice_total_amount
FROM
(SELECT return.extern_OD_id,
return.refund_it_amt AS refund_it_Amount,
return.refund_amount,
billing_tbl.invoice_ref_7,
billing_tbl.invoice_total_amount
FROM
(SELECT rrrf.extern_OD_id,
sum(rrrf.refund_it_amt) AS refund_it_amt,
sum(rrrf.refund_amount/100) refund_amount
FROM rrr__refunds_fact rrrf
JOIN Payment_TBL paymt ON paymt.payment_ref_num_2 = rrrf.extern_OD_id
WHERE rrrf.refund_status = 'completed'
AND rrrf.refund_created_date_key >= '20150401'
AND rrrf.refund_mode IN('CREDIT_CARD',
'CREDIT_EMI',
'DDCHEQUE',
'DEBIT_CARD',
'GIFT_VOUCHER',
'ICICI',
'NETBANKING',
'back_to_source')
AND rrrf.refund_mode NOT IN ('GIFT_Card')
AND paymt.payment_method_key NOT IN ('WALLET')
AND paymt.payment_ref_num_4 NOT IN ('PRICE_REFUND')
GROUP BY rrrf.extern_OD_id) RETURN
LEFT JOIN
(SELECT invoice_ref_7,
sum(invoice_total_amount) invoice_total_amount
FROM invoice_fact
WHERE invoice_type_key = 'receiv_note'
AND invoice_status_key NOT IN('voided',
'canceled',
'cancelled')
GROUP BY invoice_ref_7) billing_tbl ON RETURN.extern_OD_id =billing_tbl.invoice_ref_7
WHERE RETURN.refund_amount <> billing_tbl.invoice_total_amount
OR billing_tbl.invoice_ref_7 IS NULL) rrr
WHERE rrr.refund_it_amount >0
AND rrr.refund_amount >0

Union doesn't work when used with group by in mysql? whats wrong?

i have written a query like
(select meterID, timestamp from meter_data
where timestamp between 1369282639 AND 1369282699
AND deviceID = "1"
GROUP BY meterID)
UNION
(select meterID, timestamp from meter_data
where timestamp between 1369282739 AND 1369282799
AND deviceID = "1"
GROUP BY meterID);
i expect 2 set of data from it like - i have 4 distinct meterIDs in my table so it should return me 8 records yet its returning only 4 records
To help understand the data can yu try the following
SELECT a.meterID, MAX(b.timestamp), MAX(c.timestamp)
FROM meter_data a
LEFT OUTER JOIN meter_data b ON a.meterID = b.meterID AND b.timestamp between 1369282639 AND 1369282699 AND b.deviceID = "1"
LEFT OUTER JOIN meter_data c ON a.meterID = c.meterID AND c.timestamp between 1369282739 AND 1369282799 AND c.deviceID = "1"
GROUP BY a.meterID
This should return one row per meter id and the max timestamp within each range for that meter id.