This is my query and i need to check sub query column previousenddate in where condition without NULL.
SELECT pa.policy_id,
pa.person_id,
(
SELECT COUNT(pas.person_id)
FROM `package_assignments` pas
WHERE pas.person_id = pa.person_id
GROUP BY pas.person_id
) AS Member_Count,
pe.full_name,
pa.start_date,
pa.end_date,
(
SELECT p.end_date
FROM `package_assignments` p
WHERE p.person_id = pa.person_id
ORDER BY p.end_date DESC LIMIT 1,
1
) previousenddate
FROM `package_assignments` pa,
persons pe
WHERE end_date BETWEEN "2017-04-01"
AND "2017-04-30"
AND pa.person_id = pe.id
AND pa.rmhc_location = 5006
AND previousenddate > 1
I need to check the previousenddate column without Null For Eg:where previousenddate <> 'NULL'
Related
I have used this to get Data
SELECT customers.*, COUNT(invoice.payment_status) AS pending_invoices,sum(invoice.total ) AS total_pending_amount
FROM customers JOIN invoice ON (invoice.customer_id = customers.id)
WHERE invoice.payment_status = 'P' AND invoice.status = 'A' AND payment_followup_date IS NOT NULL AND payment_followup_date <= '2022-03-24 23:59'
GROUP BY invoice.customer_id
ORDER By payment_followup_date DESC
Now I am looking for a Query to perform an update on customers to add the current DateTime into payment_payment_followup_date and payment status = P for those customers who have more than 3 pending invoices
Try this:
UPDATE customers c
INNER JOIN (
SELECT
customer_id, COUNT(payment_status) pending_invoices
FROM invoice
WHERE payment_status = 'P' AND status = 'A'
GROUP BY customer_id
HAVING COUNT(payment_status) > 3
) i ON c.customer_id = i.customer_id
SET c.payment_payment_followup_date = CURRENT_TIMESTAMP()
c.payment_status = 'P'
WHERE c.payment_followup_date IS NOT NULL
AND c.payment_followup_date <= '2022-03-24 23:59'
I am running a query against a table and doing a left join to try and get the record from the left table with the most recent date but it's not picking up the other values relevant to the datetime column (user and notes)
SELECT
i.customer_sequence,
i.due_date,
MAX(cn.datetime) as notes_datetime,
cn.user as notes_user,
cn.notes as notes_notes
FROM
billing_invoices i
LEFT JOIN customer_notes cn
ON i.customer_sequence = cn.customer_seq
WHERE
cn.type = 'Accounts' AND
i.customer_sequence <> '0' AND
i.status = 'Unpaid' AND
i.directdebit <> 'Y'
GROUP BY
i.customer_sequence
ORDER BY
i.due_date DESC
Aggregation is not the solution here. You want the entire row from the joined table, so this suggest filtering instead. If you are running MySQL 8.0, I would recommend window functions:
SELECT *
FROM (
SELECT
i.customer_sequence,
i.due_date,
ROW_NUMBER() OVER(PARTITION BY i.customer_sequence ORDER BY cn.datetime DESC) rn,
cn.datetime as notes_datetime,
cn.user as notes_user,
cn.notes as notes_notes
FROM billing_invoices i
LEFT JOIN customer_notes cn
ON i.customer_sequence = cn.customer_seq
AND cn.type = 'Accounts'
WHERE
i.customer_sequence <> '0' AND
i.status = 'Unpaid' AND
i.directdebit <> 'Y'
) t
ORDER BY i.due_date DESC
Note that I moved the condition on the left joined table from the WHERE clause to the ON clause of the join (otherwise, this acts like an inner join).
In earlier versions, one option is a correlated subquery:
SELECT
i.customer_sequence,
i.due_date,
cn.datetime as notes_datetime,
cn.user as notes_user,
cn.notes as notes_notes
FROM billing_invoices i
LEFT JOIN customer_notes cn
ON i.customer_sequence = cn.customer_seq
AND cn.type = 'Accounts'
AND cn.datetime = (
SELECT MAX(cn1.datetime)
FROM customer_notes cn1
WHERE i.customer_sequence = cn1.customer_seq AND cn1.type = 'Accounts'
)
WHERE
i.customer_sequence <> '0' AND
i.status = 'Unpaid' AND
i.directdebit <> 'Y'
I'm writing code for the production report.
I had written this query
SELECT
P.*,
(
SELECT
COUNT(id) AS cnt
FROM
bales
WHERE
create_date < '2019-11-01' AND product_id = P.id AND(TYPE = 'bale' OR TYPE = 'bag')
) AS before_prod,
(
SELECT
COUNT(id) AS cnt
FROM
bales
WHERE
(
dispatched = '0' OR disp_bunch = '0'
) AND dispatch_date < '2019-11-01' AND product_id = P.id AND(TYPE = 'bale' OR TYPE = 'bag')
) AS before_dispatched,
(
SELECT
COUNT(id) AS cnt
FROM
bales
WHERE
create_date BETWEEN '2019-11-01' AND '2019-11-06' AND product_id = P.id AND(TYPE = 'bale' OR TYPE = 'bag')
) AS production,
(
SELECT
COUNT(id) AS cnt
FROM
bales
WHERE
(
dispatched = '0' OR disp_bunch = '0'
) AND dispatch_date BETWEEN '2019-11-01' AND '2019-11-06' AND product_id = P.id AND(TYPE = 'bale' OR TYPE = 'bag')
) AS production_dispatched,
C.name AS category_name
FROM
products P
INNER JOIN category C ON
C.id = P.category
This query is working but as I have too many records in all tables it takes too much time.
also, I need only records where before_prod, before_dispatched, production, production_dispatched all these subquery results should be greater than 0.
I tried to use having clause but it also takes too much time.
I have also tried php for loop, * LOGIC: first all products than in for loop its production. but it was much slower.*
How can I optimize my query?
You can use join instead and select case to sum your data that matches your conditions.
select p.*, t.*
from products p
inner join (
select t2.id, sum(case when create_date < '2019-11-01' then 1 else 0 end) as before_prod
, sum(case when (dispatched = '0' or disp_bunch = '0') and create_date < '2019-11-01' then 1 else 0 end) as before_dispatched
, sum(case when create_date between '2019-11-01' and '2019-11-06' then 1 else 0 end) as production
, sum(case when (dispatched = '0' or disp_bunch = '0') and create_date between '2019-11-01' and '2019-11-06' then 1 else 0 end) as production_dispatched
from bales t1
inner join product t2 on t2.id= t1.product_id
inner join category t3 on t3.id = t2.category
where t1.TYPE in ('bale', 'bag')
group by t2.id) t
on t.id = p.id
I've tried this query successfully with a limit. The following query runs endless without limit:
SELECT o.product_sku
FROM order_table o
WHERE EXISTS (SELECT 1
FROM (SELECT DISTINCT u.type_id,
u.charge_type,
u.billed_weight
FROM ups_table u
WHERE charge_type = 'order_shipping_table'
AND NOT billed_weight = '0'
) dtm
WHERE o.order_id = dtm.type_id)
GROUP BY product_sku
HAVING Count(product_sku) > 1
First of all you don't need these subqueries with DISTINCT and so on:
SELECT o.product_sku
FROM order_table o
WHERE EXISTS (SELECT 1
FROM ups_table u
WHERE charge_type = 'order_shipping_table'
AND NOT billed_weight = '0'
AND type_id=o.order_id
)
GROUP BY product_sku
HAVING Count(product_sku) > 1
I don't know your table structure (what do you want to count in the HAVING?) but you can try to change EXISTS to JOIN:
SELECT o.product_sku
FROM order_table o
JOIN ups_table u on (u.type_id=o.order_id)
AND (u.charge_type = 'order_shipping_table')
AND NOT (billed_weight = '0')
GROUP BY product_sku
HAVING Count(DISTINCT o.order_id) > 1
And you need indexes on o.order_id, o.product_sku, u.type_id,u.charge_type, u.billed_weight
I have 2 tables, named subscriptions and tags. Once in a month I will have to create tags for each order.
I have to list subscriptions without a tag for the given month (2011-10-01 or 2011-09-01 etc). This query returns 0 records:
SELECT s.id, s.active, s.status
FROM asw_subscriptions as s
LEFT JOIN asw_tags as t ON s.id = t.subscription_id
WHERE t.subscription_id IS NULL
AND t.deliveryDate = '2011-10-01'
AND s.status = '2'
AND s.active = '1'
ORDER BY s.id DESC
LIMIT 0, 25
Table Structure
subscriptions = id (int / auto), active (enum : 0,1), status (enum : 0,1)
tags = id (int / auto), deliveryDate (date), tagNumber
The problem is in clausule
t.deliveryDate = '2011-10-01' AND
You have not record on the left because condition 'IS NULL' eliminates LEFT JOIN'ed records.
So, above condition will eliminate all join products, because will never be true (there will be always null in t.deliveryDate.
Try something like this:
SELECT s.id, s.active, s.status
FROM asw_subscriptions as s
WHERE s.status = '2'
AND s.active = '1'
AND NOT EXISTS (
SELECT 1
FROM asw_tags as t
WHERE s.id = t.subscription_id
AND t.deliveryDate = '2011-10-01'
)
ORDER BY s.id DESC
LIMIT 0, 25
The problem is that you are checking the tag date on the same query that checks the existence of a tag.
Try this:
SELECT s.id, s.active, s.status
FROM
asw_subscriptions as s
LEFT JOIN (
SELECT subscription_id
FROM asw_tags
WHERE deliveryDate = '2011-10-01'
) as t ON s.id = t.subscription_id
WHERE
t.subscription_id IS NULL
AND s.status = '2'
AND s.active = '1'
ORDER BY s.id DESC
LIMIT 0, 25
Just realize that specifying condition under WHERE - you implement INNER JOIN logic, It is not what you have expected. So place entire WHERE section under ON of OUTER JOIN:
... ON s.id = t.subscription_id
AND t.subscription_id IS NULL AND
t.deliveryDate = '2011-10-01' AND
s.status = '2' AND
s.active = '1'