SQL query adding where related to sub query - mysql

Trying to get a where statement on a sub query result. The below works as I want it to, with the exception of AND low_36 != NULL. I need this to stop results where the output of low_36 is NULL.
SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 ) AS low_36
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON v_v.code = offers.code
LEFT JOIN m_f_t ON v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON v.t_t_id = m_t_t.id
WHERE status = 1
AND low_36 != NULL
LIMIT 2 OFFSET 0
I know you can not use results from subqueries in the main where statement, but this is the closest I have come to the correct result. Thank you for any feedback

Quick way would be
SELECT *
FROM
(SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 ) AS low_36
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON v_v.code = offers.code
LEFT JOIN m_f_t ON v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON v.t_t_id = m_t_t.id
WHERE status = 1) a
WHERE low_36 IS NOT NULL
LIMIT 2 OFFSET 0

I suspect you want to exclude null values in the subquery itself, thereby avoiding nullifying your aggregate value. Try this:
SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 and price is not null) AS low_36,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON m_v.code = offers.code
LEFT JOIN m_f_t ON m_v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON m_f_t.t_t_id = m_t_t.id
WHERE status = 1
LIMIT 2 OFFSET 0

Related

Count Total from Multiple Tables

I have list table that basically contains same field on each part.
- p_ticket1_m_site_data | - p_ticket1_ticket | - p_ticket1_last_row
- p_ticket2_m_site_data | - p_ticket2_ticket | - p_ticket2_last_row
- p_ticket3_m_site_data | - p_ticket3_ticket | - p_ticket3_last_row
I can do a count on each table individually:
SELECT COUNT( * ) AS tot_sites, IFNULL( COUNT(
CASE WHEN p_ticket1_m_site_data.m_date_target = DATE( NOW( ) )
THEN 1
ELSE NULL
END ),0) AS todays_target, IFNULL( COUNT(
CASE WHEN (
p_ticket1_m_site_data.m_date_target = DATE( NOW( ) )
AND p_ticket1_ticket.t_status =9 )
THEN 1
ELSE NULL
END ),0
) AS todays_achieve, IFNULL( COUNT(
CASE WHEN p_ticket1_ticket.t_status =9
THEN 1
ELSE NULL
END ),0 ) AS tot_in
FROM p_ticket1_m_site_data
LEFT JOIN p_ticket1_last_row ON p_ticket1_last_row.t_m_id = p_ticket1_m_site_data.m_id
AND p_ticket1_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket1_ticket ON p_ticket1_ticket.t_id = p_ticket1_last_row.t_id
WHERE p_ticket1_m_site_data.m_status =1
What should i do if i want to count all total sites from ticket1, ticket2, ticket3 ?
Please help me guys, thanks . . .
Example use UNION ALL:
I just using UNION ALL in my code above for ticket1 and ticket2, but its not what i want.
My expectation output is count all the ticket tables, so the view is tot_sites (from all ticket), todays_target(from all ticket), todays_achieve(from all ticket), and tot_in(from all ticket)
If you are sure that your tables have the same columns, you should use UNION ALL with CTE
WITH CTE AS (
SELECT *
FROM p_ticket1_m_site_data
UNION ALL
SELECT *
FROM p_ticket2_m_site_data
UNION ALL
...
)
SELECT COUNT(*), ...
FROM CTE
WHERE CTE.m_status = 1
CTE
UNION ALL
You can union the three sets of tables in a sub query and then do your counts in the main query , something like this in principal
SELECT COUNT( * ) AS tot_sites, IFNULL( COUNT(
CASE WHEN m_date_target = DATE( NOW( ) )
THEN 1
ELSE NULL
END ),0) AS todays_target, IFNULL( COUNT(
CASE WHEN (m_date_target = DATE( NOW( ) )
AND t_status =9 )
THEN 1
ELSE NULL
END ),0
) AS todays_achieve, IFNULL( COUNT(
CASE WHEN t_status =9
THEN 1
ELSE NULL
END ),0 ) AS tot_in
from
(
select *
FROM p_ticket1_m_site_data
LEFT JOIN p_ticket1_last_row ON p_ticket1_last_row.t_m_id = p_ticket1_m_site_data.m_id
AND p_ticket1_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket1_ticket ON p_ticket1_ticket.t_id = p_ticket1_last_row.t_id
WHERE p_ticket1_m_site_data.m_status =1
union all
select *
frOM p_ticket2_m_site_data
LEFT JOIN p_ticket2_last_row ON p_ticket2_last_row.t_m_id = p_ticket2_m_site_data.m_id
AND p_ticket2_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket2_ticket ON p_ticket2_ticket.t_id = p_ticket2_last_row.t_id
WHERE p_ticket2_m_site_data.m_status =1
union all
select *
fROM p_ticket3_m_site_data
LEFT JOIN p_ticket3_last_row ON p_ticket3_last_row.t_m_id = p_ticket3_m_site_data.m_id
AND p_ticket3_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket3_ticket ON p_ticket3_ticket.t_id = p_ticket3_last_row.t_id
WHERE p_ticket3_m_site_data.m_status =1
) j;
Which could be tidied up. If this doesn't work for you please add sample data and expected output for your 3 tables as text to the question and I will review.

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)

Operand should contain 1 column(s) - in mysql query

I have the following complex query that is giving me an error
Operand should contain 1 column(s)
Can anyone suggest what is wrong
SELECT
t.user_id AS user_id,
t.organisation_id AS organisation_id,
t.firstname AS firstname,
t.surname AS surname,
t.username AS username,
t.year_id AS year_id,
t.form_name AS form_name,
t.House AS House,
rcPoints.total AS milestoneRedeemedCodesTotal,
rcFilteredPoints.total AS redeemedCodesTotalFiltered,
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) AS redeemedCodesTotalAvailableFiltered,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
) * 1000
) AS redeemedCodesTotalTowardsMilestone,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
)
) AS redeemedCodesMilestoneTriggers,
COALESCE (milestoneHistory.total, 0) AS historyTotal
FROM
`myuser` `t`
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcPoints ON (rcPoints.user_id = t.user_id)
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcFilteredPoints ON (
rcFilteredPoints.user_id = t.user_id
)
LEFT JOIN (
SELECT
mh.user_id AS user_id,
mh.milestone_id AS milestone_id,
MAX(mh.points_when_triggered) AS total
FROM
`milestone_history` `mh`
WHERE
mh.milestone_id = 13
GROUP BY
mh.user_id
) AS milestoneHistory ON (
milestoneHistory.user_id = t.user_id
)
WHERE
(
(
SELECT
COALESCE (count(*), 0)
FROM
milestone_history mha
WHERE
mha.milestone_id = 13
AND mha.user_id = t.user_id
) = 0
)
AND (t.organisation_id = 58022)
AND
(
SELECT * FROM
redeemed_codes t1
WHERE
organisation_id = 1
AND
(
SELECT
sum(school_points)
FROM
redeemed_codes t2
WHERE
t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
GROUP BY
t.user_id
ORDER BY
redeemedCodesMilestoneTriggers DESC
LIMIT 1
Your query might have multiple errors, but this condition in the WHERE clause is definitely suspect and would lead to that error:
AND (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
I have no idea what you are trying to do. Sometimes, the solution is simply EXISTS:
EXISTS (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
)

Mysql query Full Join

I have three tables in my mysql db
dc_match_entries with player_id, goals, yellow cards, own goals etc for each match
dc_player player_id, team_id etc etc
dc_team team_is, some stuff etc etc
And i have this query too
SELECT
dc_player. *,
dc_team.name AS team_name,
dc_team.abbr_name AS team_abbr_name,
COUNT( dc_match_entry.player_id ) AS played,
AVG( dc_match_entry.vote ) AS vote_average,
SUM( dc_match_entry.goal ) AS goal_sum,
SUM( dc_match_entry.own_goal) AS own_goal_sum,
SUM( dc_match_entry.vote ) *10
+ SUM( dc_match_entry.goal ) *10
+ SUM( dc_match_entry.r_card ) *-10
+ SUM( dc_match_entry.y_card ) *-5
+ SUM( dc_match_entry.own_goal ) *-10 AS score,
SUM( dc_match_entry.y_card ) AS y_card_sum,
SUM( dc_match_entry.r_card ) AS r_card_sum
FROM
dc_player,
dc_match_entry,
dc_team
WHERE
dc_player.id = dc_match_entry.player_id AND
dc_player.team = dc_team.id
GROUP BY
dc_player.id
Sadly this query doesn't show players which havent played any match in the competition (since they have no dc_match_entry entries). I can't find a simple (and possibly clear) way to show those players too (full join?)
PS:
this query is nested into a bigger one :
SELECT
L.id,
L.role,
L.first_name,
L.last_name,
L.birth_date,
L.team_name,
L.team_abbr_name,
L.team AS team_id,
L.photo,
L.email,
L.played,
L.vote_average,
L.goal_sum AS goal,
L.own_goal_sum AS own_goal,
L.score +
IFNULL(L.c_mvp, 0)*15
+ IFNULL(unbeaten, 0)*50*IF(L.role='P', 1, 0) AS score,
L.y_card_sum AS y_card,
L.r_card_sum AS r_card,
IFNULL(L.c_mvp, 0) AS mvp,
IFNULL(unbeaten, 0) AS unbeaten
FROM (
SELECT * FROM (
SELECT
dc_player. *,
dc_team.name AS team_name,
dc_team.abbr_name AS team_abbr_name,
COUNT( dc_match_entry.player_id ) AS played,
AVG( dc_match_entry.vote ) AS vote_average,
SUM( dc_match_entry.goal ) AS goal_sum,
SUM( dc_match_entry.own_goal) AS own_goal_sum,
SUM( dc_match_entry.vote ) *10
+ SUM( dc_match_entry.goal ) *10
+ SUM( dc_match_entry.r_card ) *-10
+ SUM( dc_match_entry.y_card ) *-5
+ SUM( dc_match_entry.own_goal ) *-10 AS score,
SUM( dc_match_entry.y_card ) AS y_card_sum,
SUM( dc_match_entry.r_card ) AS r_card_sum
FROM
dc_player,
dc_match_entry,
dc_team
WHERE
dc_player.id = dc_match_entry.player_id AND
dc_player.team = dc_team.id
GROUP BY
dc_player.id
) LOL
LEFT JOIN (
SELECT
COUNT(dc_match.mvp) c_mvp,
mvp AS player_id
FROM dc_match
WHERE
dc_match.mvp IS NOT NULL
GROUP BY dc_match.mvp
) ROFL
ON ROFL.player_id = LOL.id
ORDER BY
LOL.score DESC
) L
LEFT OUTER JOIN(
SELECT
dc_player.id,
COUNT(dc_match.id) AS unbeaten
FROM
dc_match,
dc_match_entry,
dc_player
WHERE
(
(dc_player.team=dc_match.host AND
dc_match.guest_score=0
) OR
(
dc_player.team=dc_match.guest AND
dc_match.host_score=0
)
) AND
dc_player.id = dc_match_entry.player_id AND dc_match.id = dc_match_entry.match_id
GROUP BY
dc_player.id
) I
ON
L.id = I.id
WHERE
L.team = 2
GROUP BY
id
ORDER BY
role DESC, score DESC
You need to use a LEFT JOIN like this:
SELECT ...
FROM dc_player
JOIN dc_team ON (dc_player.team = dc_team.id)
LEFT JOIN dc_match_entry ON (dc_player.id = dc_match_entry.player_id)
GROUP BY dc_player.id
This will return a row for each player whether or not they have any match entries.

How to merge the result of this 2 queries in mysql server

I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )
Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC