Multiple Subqueries in where clause - mysql

I need two filer data in sub query. This is my sub query one
(select CAST(to_char(date_trunc('day', now()-to_date(max(date_time),'yyyy-MM-dd HH24:mi:ss')), 'dd')AS INT) AS monthDiff FROM loyalty_scheme L
JOIN subscribe_merchant S ON (L.scheme_id = S.schemerefid)
JOIN transaction T ON (S.unipoint_customer_ref_id = T.unipoint_customer_ref_id) where (T.unipoint_customer_ref_id IN( select unipoint_customer_ref_id FROM subscribe_merchant where schemerefid = (SELECT scheme_id from loyalty_scheme where minimum_purchase_amount =(SELECT min(minimum_purchase_amount) from loyalty_scheme where merchant_id = 11 )GROUP BY scheme_id) ) )GROUP BY T.unipoint_customer_ref_id )
it gives int value as a new column
--------
monthDiff
--------
5
---------
370
---------
I need to compare this two value with another sub query and get greater than value. This is the other sub query
((SELECT CAST(to_char(date_trunc('day', to_date(demoting_time_period,'yyyy-MM-dd HH24:mi:ss')), 'dd')AS INT)*31 AS demortProd from loyalty_scheme where minimum_purchase_amount =(SELECT min(minimum_purchase_amount) from loyalty_scheme where merchant_id = 11)GROUP BY scheme_id ))
It returns this as new column
---------------
demortProd
---------------
31
---------------
I need to find greater than 31.
I used where clause as below:
SELECT *
FROM loyalty_scheme L
JOIN subscribe_merchant S ON (L.scheme_id = S.schemerefid)
JOIN transaction T ON (S.unipoint_customer_ref_id = T.unipoint_customer_ref_id) WHERE (select CAST(to_char(date_trunc('day', now()-to_date(max(date_time),'yyyy-MM-dd HH24:mi:ss')), 'dd')AS INT) AS monthDiff FROM loyalty_scheme L
JOIN subscribe_merchant S ON (L.scheme_id = S.schemerefid)
JOIN transaction T ON (S.unipoint_customer_ref_id = T.unipoint_customer_ref_id) where (T.unipoint_customer_ref_id IN( select unipoint_customer_ref_id FROM subscribe_merchant where schemerefid = (SELECT scheme_id from loyalty_scheme where minimum_purchase_amount =(SELECT min(minimum_purchase_amount) from loyalty_scheme where merchant_id = 11 )GROUP BY scheme_id) ) )GROUP BY T.unipoint_customer_ref_id ) <
(SELECT CAST(to_char(date_trunc('day', to_date(demoting_time_period,'yyyy-MM-dd HH24:mi:ss')), 'dd')AS INT) AS demortProd from loyalty_scheme where minimum_purchase_amount =(SELECT min(minimum_purchase_amount) from loyalty_scheme where merchant_id = 11)GROUP BY scheme_id )
but it throws an error:
ERROR: more than one row returned by a subquery used as an expression
Please help me solve this error

Related

Count union of two table that has subquery

I have this working query. It has count with subquery.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) t
now I need to union with different table and get the total from both table. This code could get count record but the value is incorrect.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
UNION
SELECT
COUNT(aset)
FROM
`public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) z
Please assist me in getting the query correct. Thanks in advance
Use SELECT COUNT(DISTINCT aset) to get your counts, and then add them together.
SELECT t1.total + t2.total AS total
FROM (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t1
CROSS JOIN (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t2

Sql server errors in query

I am trying to collaborate 3 queries to perform arithmetic operation. The queries are shown in
(SELECT ITEM_ID,ISNULL(SUM(REC_GOOD_QTY),0)
FROM INVENTORY_ITEM
WHERE COMPANY_ID = 1
AND INVENTORY_ITEM.COMPANY_BRANCH_ID = 1
AND INVENTORY_ITEM.INV_ITEM_STATUS = 'Inward'
AND GRN_DATE < CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY INVENTORY_ITEM.ITEM_ID) -
(SELECT ITEM_ID, SUM ( TOTAL_LITRE )
FROM STOCK_REQUISITION_ITEM B, STOCK_REQUISITION A
WHERE A.ID = B.REQUISITION_ID
AND A.COMPANY_ID = 1
AND A.REQ_FROM_BRANCH_ID = 1
AND A.REQUISITION_DATE < CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY B.ITEM_ID) +
(SELECT ITEM_ID, SUM ( RETURN_QUANTITY )
FROM STOCK_RETURN_ITEM B, STOCK_RETURN A
WHERE A.ID = B.STOCK_RETURN_ID
AND A.COMPANY_ID = 1
AND A.COMPANY_BRANCH_ID = 1
AND A.RETURN_DATE <= CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY B.ITEM_ID)
I am getting this error.
[Err] 42000 - [SQL Server]Incorrect syntax near '-'.
42000 - [SQL Server]Incorrect syntax near '+'
Not much to go on here for details. And we aren't actually sure if you are using mysql or sql server but pretty sure you are using sql server. I think you can accomplish what you are trying to do with something along these lines.
with Iventory as
(
SELECT i.ITEM_ID
, GoodQty = ISNULL(SUM(i.REC_GOOD_QTY), 0)
FROM INVENTORY_ITEM i
WHERE COMPANY_ID = 1
AND i.COMPANY_BRANCH_ID = 1
AND i.INV_ITEM_STATUS = 'Inward'
AND i.GRN_DATE < '2017-01-10'
GROUP BY i.ITEM_ID
)
, StockRequisition as
(
SELECT ITEM_ID
, TotalLitre = SUM(TOTAL_LITRE)
FROM STOCK_REQUISITION_ITEM B
JOIN STOCK_REQUISITION A ON A.ID = B.REQUISITION_ID
WHERE A.COMPANY_ID = 1
AND A.REQ_FROM_BRANCH_ID = 1
AND A.REQUISITION_DATE < '2017-01-10'
GROUP BY B.ITEM_ID
)
StockReturn as
(
SELECT ITEM_ID
, ReturnQuantity = SUM(RETURN_QUANTITY)
FROM STOCK_RETURN_ITEM B
JOIN STOCK_RETURN A ON A.ID = B.STOCK_RETURN_ID
WHERE A.COMPANY_ID = 1
AND A.COMPANY_BRANCH_ID = 1
AND A.RETURN_DATE <= '2017-01-10'
GROUP BY B.ITEM_ID
)
select i.ITEM_ID
, MyCalculation = i.GoodQty - isnull(Req.TotalLitre, 0) + isnull(sr.ReturnQuantity, 0)
from Inventory i
left join StockRequisition sr on sr.ITEM_ID = i.ITEM_ID
left join StockReturn Req on Req.ITEM_ID = i.ITEM_ID
In your queries you always returns two fields ITEM_ID and a numeric field.
To apply an arithmetical operation you must return one numeric field
The first query:
SELECT ITEM_ID,ISNULL(SUM(REC_GOOD_QTY),0)
becomes
SELECT ISNULL(SUM(REC_GOOD_QTY),0)
The second query:
SELECT ITEM_ID, SUM ( TOTAL_LITRE )
becomes
SELECT SUM ( TOTAL_LITRE )
The third query:
SELECT ITEM_ID, SUM ( RETURN_QUANTITY )
becomes
SELECT SUM ( RETURN_QUANTITY )
So the GROUP BY returns more than one row per query
UPDATE
i try to rewrite your query:
SELECT DISTINCT ii.item_id,
ISNULL(
(SELECT SUM(ii2.rec_good_qty)
FROM inventory_item ii2
WHERE ii2.item_id = ii.item_id
AND ii.company_id = 1
AND ii.company_branch_id = 1
AND ii.inv_item_status = 'Inward'
AND ii.grn_date < CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) -
ISNULL(
(SELECT SUM(total_litre)
FROM stock_requisition_item b
JOIN stock_requisition a
ON a.id = b.requisition_id
WHERE a.company_id = 1
AND a.req_from_branch_id = 1
AND a.requisition_date < CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) +
ISNULL(
(SELECT SUM(return_quantity)
FROM stock_return_item b
JOIN stock_return a
ON a.id = b.stock_return_id
WHERE a.company_id = 1
AND a.company_branch_id = 1
AND a.return_date <= CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) AS result
FROM inventory_item ii
WHERE ii.company_id = 1
AND ii.company_branch_id = 1
AND ii.inv_item_status = 'Inward'
AND ii.grn_date < CAST('2017-01-10 00:00:00.0' AS DATETIME)

SQL query joining a few tables (MySQL)

I need a "little" help with an SQL query (MySQL).
I have the following tables:
COURIERS table:
+------------+
| COURIER_ID |
+------------+
DELIVERIES table:
+-------------+------------+------------+
| DELIVERY_ID | COURIER_ID | START_DATE |
+-------------+------------+------------+
ORDERS table:
+----------+-------------+-------------+
| ORDER_ID | DELIVERY_ID | FINISH_DATE |
+----------+-------------+-------------+
COORDINATES table:
+-------------+-----+-----+------+
| DELIVERY_ID | LAT | LNG | DATE |
+-------------+-----+-----+------+
In the real database I have more columns in each table, but for this example the above columns are enough.
What do I need?
An SQL query that returns all couriers [COURIER_ID], their last
delivery [DELIVERY_ID] (based on last START_DATE), the
delivery's last coordinate [LAT and LNG] (based on last DATE) and the remaining orders count (total of orders of the last delivery that have no FINISH_DATE).
A courier can have no deliveries, in this case I want DELIVERY_ID =
NULL, LAT = NULL and LNG = NULL in the result.
A delivery can have no coordinates, in this case I want LAT = NULL
and LNG = NULL in the result.
What was I able to do?
SELECT c.`COURIER_ID`,
d.`DELIVERY_ID`,
r.`LAT`,
r.`LNG`,
(SELECT COUNT(DISTINCT `ORDER_ID`)
FROM `ORDERS`
WHERE `DELIVERY_ID` = d.`DELIVERY_ID`
AND `FINISH_DATE` IS NULL) AS REMAINING_ORDERS
FROM `COURIERS` AS c
LEFT JOIN `DELIVERIES` AS d USING (`COURIER_ID`)
LEFT JOIN `COORDINATES` AS r ON r.`DELIVERY_ID` = d.`DELIVERY_ID`
WHERE (CASE WHEN
(SELECT MAX(`START_DATE`)
FROM `DELIVERIES`
WHERE `COURIER_ID` = c.`COURIER_ID`) IS NULL THEN d.`START_DATE` IS NULL ELSE d.`START_DATE` =
(SELECT MAX(`START_DATE`)
FROM `DELIVERIES`
WHERE `COURIER_ID` = c.`COURIER_ID`) END)
AND (CASE WHEN
(SELECT MAX(`DATE`)
FROM `COORDINATES`
WHERE `DELIVERY_ID` = d.`DELIVERY_ID`) IS NULL THEN r.`DATE` IS NULL ELSE r.`DATE` =
(SELECT MAX(`DATE`)
FROM `COORDINATES`
WHERE `DELIVERY_ID` = d.`DELIVERY_ID`) END)
GROUP BY c.`COURIER_ID`
ORDER BY d.`START_DATE` DESC
The problem is that this query is very slow (from 5 to 20 seconds) when I have over 5k COORDINATES and it does not returns all couriers sometimes.
Thank you so much for any solution.
Try this:
SELECT C.COURIER_ID, D.DELIVERY_ID, D.START_DATE, D.FINISH_DATE,
B.LAT, B.LNG, B.DATE, C.NoOfOrders
FROM COURIERS C
LEFT JOIN ( SELECT *
FROM (SELECT *
FROM DELIVERIES D
ORDER BY D.COURIER_ID, D.START_DATE DESC
) A
GROUP BY COURIER_ID
) AS A ON C.COURIER_ID = A.COURIER_ID
LEFT JOIN ( SELECT *
FROM (SELECT *
FROM COORDINATES CO
ORDER BY CO.DELIVERY_ID, CO.DATE DESC
) B
GROUP BY CO.DELIVERY_ID
) AS B ON A.DELIVERY_ID = B.DELIVERY_ID
LEFT JOIN ( SELECT O.DELIVERY_ID, COUNT(1) NoOfOrders
FROM ORDERS O WHERE FINISH_DATE IS NULL
GROUP BY O.DELIVERY_ID
) AS C ON A.DELIVERY_ID = C.DELIVERY_ID;
I haven't been able to test this query since I don't have a mysql database set up right now, much less with this schema and sample data. But I think this will work for you:
select
c.courier_id
, d.delivery_id
, co.lat
, co.lng
, oc.cnt as remaining_orders
from
couriers c
left join (
select
d.delivery_id
, d.courier_id
from
deliveries d
inner join (
select
d.delivery_id
, max(d.start_date) as start_date
from
deliveries d
group by
d.delivery_id
) dmax on dmax.delivery_id = d.delivery_id and dmax.start_date = d.start_date
) d on d.courier_id = c.courier_id
left join (
select
c.delivery_id
, c.lat
, c.lng
from
coordinates c
inner join (
select
c.delivery_id
, max(c.date) as date
from
coordinates c
group by
c.delivery_id
) cmax on cmax.delivery_id = c.delivery_id and cmax.date = c.date
) co on co.delivery_id = d.delivery_id
left join (
select
o.delivery_id
, count(o.order_id) as cnt
from
orders o
where
o.finish_date is null
group by
o.delivery_id
) oc on oc.delivery_id = d.delivery_id

Coalesce whole records in MySQL

I'm currently coallescing fields individually in MySQL queries, but I would like to coalesce whole records.
Is this possible?
SELECT la.id,
COALESCE(( SELECT name FROM lookup_changed l0,
( SELECT MAX(id) id
FROM lookup_changed
WHERE lookup_id = 26
) l1
WHERE l0.id = l1.id
), la.name) name,
COALESCE(( SELECT msisdn FROM lookup_changed l0,
( SELECT MAX(id) id
FROM lookup_changed
WHERE lookup_id = 26
) l1
WHERE l0.id = l1.id
), la.msisdn) msisdn
FROM lookup_added la
WHERE la.id = 26
#Alma Do - the pseudo-SQL is:
SELECT la.id,
MULTICOALESCE(( SELECT <name, msisdn> FROM lookup_changed l0,
( SELECT MAX(id) id
FROM lookup_changed
WHERE lookup_id = 26
) l1
WHERE l0.id = l1.id
), <la.name, la.msisdn>) <name, msisdn>
FROM lookup_added la
WHERE la.id = 26
Since COALESCE() "return[s] the first non-NULL argument", it sounds like you want to retreive the "first non-NULL result from a set for queries":
-- syntax error
SELECT COALESCE(
SELECT a FROM ta,
SELECT b FROM tb
);
-- roughly equates to
( SELECT a AS val FROM ta WHERE a IS NOT NULL ORDER BY a LIMIT 1 )
UNION
( SELECT b AS val FROM tb WHERE b IS NOT NULL ORDER BY b LIMIT 1 )
ORDER BY val LIMIT 1 ;
Comments:
I added ORDER BY clauses, otherwise "first row" means nothing
the inner LIMIT 1 clauses are optional (but allow early trimming of sub-results)
the parenthesis around the sub queries are mandatory

MySQL Stored procedure says alias is undefined in select statement

I have the following statement, which produces this error. Apparently the alias "R" in the first line of the select statement is not declared, but it's right there at the end of the statement. Anyone have any ideas?
#1327 - Undeclared variable: R
CREATE PROCEDURE `get_series_completion`(IN team1_id INT, IN team2_id INT, IN round_shortname VARCHAR(5))
BEGIN
DECLARE num_games_total, num_games_played INT;
SELECT COUNT(*) INTO num_games_played, R.games_per_series INTO num_games_total
FROM (
SELECT game_id
FROM team_games
WHERE team_id IN (team1_id, team2_id)
GROUP BY game_id
HAVING COUNT(*) = 2
AND SUM(standing = 0) = 0
) AS S, rounds AS R ON R.round_shortname = round_shortname;
SELECT num_games_played/num_games_total;
END$$
You should select all columns before into clause, Your query should be:
SELECT COUNT(*), R.games_per_series INTO num_games_played, num_games_total
FROM (
SELECT game_id
FROM team_games
WHERE team_id IN (team1_id, team2_id)
GROUP BY game_id
HAVING COUNT(*) = 2
AND SUM(standing = 0) = 0
) AS S
LEFT OUTER JOIN rounds AS R ON R.round_shortname = round_shortname;
or
SELECT COUNT(*), R.games_per_series INTO num_games_played, num_games_total
FROM (
SELECT game_id
FROM team_games
WHERE team_id IN (team1_id, team2_id)
GROUP BY game_id
HAVING COUNT(*) = 2
AND SUM(standing = 0) = 0
) AS S, rounds AS R
WHERE R.round_shortname(+) = round_shortname; -- implicit left outer join