Filtering empty rows from SQL query - mysql

I am trying to form an SQL query to retrieve some records, however the issue I am having is that my query retrieving empty rows.
The query below retrieves the following rows, however I need the last few rows not to appear. I tried adding AND vanDeduction != '' to the end of this query, but this makes it miss important data.
SELECT rnumber,date,grossInvoice,sTaxFee1Charged,vanDeduction
FROM ledger
where rnumber = 'R-022074'
Thank you for your help!

You seem to want:
SELECT rnumber, date, grossInvoice, sTaxFee1Charged, vanDeduction
FROM ledger
WHERE rnumber = 'R-022074' AND
(grossInvoice > 0 or sTaxFee1Charged > 0 or driverPayment > 0);

Related

MySQL GROUP BY HAVING returns nothing

I have many categories with the same name and parent in my Opencart database (duplicates). Need to find all of them. That's my query:
SELECT *
FROM
(SELECT `oc_category`.category_id,
`oc_category`.parent_id,
`oc_category_description`.name
FROM `oc_category`, `oc_category_description`
WHERE `oc_category`.category_id = `oc_category_description`.category_id
) cats
GROUP BY `cats`.parent_id, `cats`.name
HAVING COUNT(*) > 1
But this query returns nothing. Please tell me if I'm wrong.
No problem with the query, it does work, check this out:
http://sqlfiddle.com/#!9/3d170/4
Please fiddle with that and populate it with the data which produces no records, and add it to your question.

MySQL group by DAY in same table not working when count zero

My following query not return row when COUNT(*) result return 0 row
SELECT COUNT(id) test,
UNIX_TIMESTAMP(my_time)*1000 d
FROM chat_table
WHERE dept_id = 5
AND my_time >="2015-03-30"
GROUP BY DAY(my_time)
ORDER BY d ASC;
I need GROUP BY day even return 0 row. How can left join in same table? or any idea?
You can only have groups based on values that exist. If a value, for example, timestamp '2015-04-01 12:00:00' does not exist in your table, it cannot be part of the result.
You can work around this by:
handling the results of the query in a programming language, supplementing count 0 for all rows that are missing
OR creating a reference table that contains all timestamps
OR manually injecting all timestamps using a subquery and union.
The best option is the first: keep your query as it is, but write logic in the program that starts the query to automatically assume that the count is zero if the timestamp is not in the result set.
For example, in PHP:
$countsPerTimestamp = array();
foreach ($stmt->fetchAll() as $row) {
$countsPerTimestamp[$row['d']] = $row['test'];
}
$searchTimestamp = '2015-04-05 12:13:14';
if (isset($countsPerTimestamp[$searchTimestamp])) {
echo 'Count for now is: ' . $countsPerTimestamp[$searchTimestamp];
}
else {
echo 'Count for now is: 0';
}
If your table has data on every day but the where clause is filtering it out, then the easiest solution is to use conditional aggregation:
SELECT SUM(dept_id = 5) as test,
UNIX_TIMESTAMP(my_time)*1000 as d
FROM chat_table
WHERE my_time >= '2015-03-30'
GROUP BY DAY(my_time)
ORDER BY d ASC;
If those conditions are not true, then you need to start with a list of all the dates and use left join.

my sub query is taking too much time

I have simple query but it is taking too much time for execution.
query:
SELECT a.primarykey,
a.SID,
a.VID,
a.topic,
a.dstart,
a.dstop,
a.vresult,
a.dstart1,
a.dstart2,
( SELECT MIN(d.vresult)
FROM _temp._pb_1_1_4_1 d
WHERE d.dstart1 > a.dstart1
) as _DOP0
FROM _temp._pb_1_1_4_1 a
column dstart1 is indexed.
dstart1 is Date type column.
Please help me to optimized above query.
if I remove d.dstart1 > a.dstart1 from the WHERE clause then query run very fast.
whenI explain the query it gives "Range checked for each record (index map: 0x1)"
I want to achieve minimum value of vresult for each row.
For each row , First filter all the records which has greater value of dstart1 for the same table and then find min(vresult) for that row.
Without knowing anything about what you're trying to do... this query should return the same results and has been removed the unnecessary calculations:
select a.primarykey, a.SID, a.VID, a.topic, a.dstart, a.dstop,
a.vresult, a.dstart1, a.dstart2, (
select MIN(d.vresult)
from _temp._pb_1_1_4_1 d
where d.dstart1 > a.dstart1) _DOP0
from _temp._pb_1_1_4_1 a
Anyway, it would help to understand what you're trying to do with that query.

Why this Query takes such a long time to execute

I have three tables
glSalesJournal
HMISAdd
HMISMain
Now what i am trying to do is add the glSalesJournal amt with HMISAdd amt while grouping up with various Fields and inserting the result into glSalesJournal
The glSalesJournal contains 633173 records
The HMISAdd contains 4193 records
HMISAdd and glSalesJournal contains the same columns which are
loc
glAcct
glSubAcct
batchNbr
contractNbr
amt
I added indexes to the table still the results are the same.
Here is my code:
INSERT INTO hmismain
(loc,
glacct,
subacct,
batchnbr,
contractnbr,
amt)
SELECT glsalesjournal.loc,
glsalesjournal.glacct,
glsalesjournal.glsubacct,
( glsalesjournal.amt + hmisadd.amt ) AS sumAmt,
glsalesjournal.batchnbr,
glsalesjournal.salescontnbr
FROM glsalesjournal
LEFT OUTER JOIN hmisadd
ON ( glsalesjournal.loc = hmisadd.loc
AND glsalesjournal.glacct = hmisadd.glacct
AND glsalesjournal.glsubacct = hmisadd.subacct
AND glsalesjournal.batchnbr = hmisadd.batchnbr
AND glsalesjournal.salescontnbr = hmisadd.contractnbr )
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
The time taken by the script to execute is more than 2 hours. Even when I limit the Records to 100 the time taken is the same.
Can someone please guide me how can I optimize the script.
Thanks
1) It looks like it's a one off query, am I correct here? If not than you are inserting the same data into hmismain table every time.
2) You are grouping on fields from TWO separate tables, so no amount of indexing will ever help you. The ONLY index that will help is an index over a view linking these two tables in the same way.
Further note:
What is the point of
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
You are grouping the data by the same fields twice
glsalesjournal.loc, hmisadd.loc
glsalesjournal.glacct, hmisadd.glacct,
...
Remove the duplicates from GROUP BY and it should run fast
Did you add an index on this fields:
glSalesJournal.loc
glSalesJournal.glAcct
glSalesJournal.glSubAcct
glSalesJournal.batchNbr
glSalesJournal.salesContNbr
HMISAdd.Loc
HMISAdd.GlAcct
HMISAdd.SubAcct
HMISAdd.batchNbr
HMISAdd.contractNbr
If this fields are unindexed, it will perform fulltable scan for each individual record thus causing slow performance.
MySQL Create Index Syntax

MySQL update with two subqueries

I'm trying to update one column of MySQL table with subquery that returns a date, and another subquery for the WHERE clause.
Here is it:
UPDATE wtk_recur_subs_temp
SET wtk_recur_date = (SELECT final_bb.date
FROM final_bb, wtk_recur_subs
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn)
WHERE wtk_recur_subs_temp.wtk_recur_msisdn IN (select final_bb.msisdn
from final_bb)
The response from the MySQL engine is "Subquery returns more than 1 row".
Use:
UPDATE wtk_recur_subs_temp,
final_bb,
wtk_recur_subs
SET wtk_recur_subs_temp.wtk_recur_date = final_bb.date
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn
AND wtk_recur_subs_temp.wtk_recur_msisdn = final_bb.msisdn
The error is because:
SET wtk_recur_date = (SELECT final_bb.date
FROM final_bb, wtk_recur_subs
WHERE final_bb.msisdn = wtk_recur_subs.wtk_recur_msisdn)
...the final_bb.date value is all the date values where the final_bb and wtk_recur_subs msisdn column values match.
This may come as an utter shock to you, but one of your subqueries is returning more than one row!
This isn't permitted in the circumstance you've set up. Each of those two subqueries must return one and only one row. Or no rows.
Perform each subquery on it's own and determine which one is returning more than one row. If they shouldn't return more than one row, your data may be wrong. If they should return more than one row, you'll either want to modify the data so they don't (as I assume you expect), or add a LIMIT clause. Or add an aggregate function (like MAX) outside the query to do something proper with the multiple rows being returned.