I wrote mysql query which use subquery. I can't understand why mysql shows me 'Unknown column 'T.TICKETID' in 'where clause'' in subquery. For MSSQL it works without problem.
SELECT #PERIODTYPE := 'Y';
SELECT
#PERIODTYPE,
CASE
WHEN #PERIODTYPE = 'W' THEN DATE_FORMAT(R.DATENEW,'%u')
WHEN #PERIODTYPE = 'M' THEN DATE_FORMAT(R.DATENEW,'%Y-%m')
WHEN #PERIODTYPE = 'Y' THEN DATE_FORMAT(R.DATENEW,'%Y')
ELSE DATE_FORMAT(R.DATENEW,'%Y-%m-%d')
END `Period`,
DATE_FORMAT(MIN(R.DATENEW),'%Y-%m-%d') min_date,
DATE_FORMAT(MAX(R.DATENEW),'%Y-%m-%d') max_date,
COUNT(*) Transactions,
SUM(SQ.`Sold Units`) `Sold Units`,
FORMAT(MAX(P.TOTAL), 2) `Largest Order`,
FORMAT(SUM(P.TOTAL), 2) `Total $ Sold`,
FORMAT(SUM(TXL.AMOUNT), 2) `Total Tax $ Collected`
FROM RECEIPTS R INNER JOIN TAXLINES TXL ON R.ID = TXL.RECEIPT
INNER JOIN TAXES TX ON TXL.TAXID = TX.ID
INNER JOIN TAXCATEGORIES TXC ON TX.CATEGORY = TXC.ID
INNER JOIN PAYMENTS P ON P.RECEIPT = R.ID
INNER JOIN TICKETS T ON R.ID = T.ID
CROSS JOIN (SELECT SUM(TL.UNITS) 'Sold Units' FROM TICKETLINES TL WHERE T.TICKETID = TL.TICKET) SQ
GROUP BY CASE
WHEN #PERIODTYPE = 'W' THEN DATE_FORMAT(R.DATENEW,'%u')
WHEN #PERIODTYPE = 'M' THEN DATE_FORMAT(R.DATENEW,'%Y-%m')
WHEN #PERIODTYPE = 'Y' THEN DATE_FORMAT(R.DATENEW,'%Y')
ELSE DATE_FORMAT(R.DATENEW,'%Y-%m-%d')
END
ORDER BY R.DATENEW
Update 1
I replaced table name (TICKETS) instead of alias (T). I got error. Please, see the screenshot.
SELECT #PERIODTYPE := 'D';
SELECT
#PERIODTYPE,
CASE
WHEN #PERIODTYPE = 'W' THEN DATE_FORMAT(R.DATENEW,'%u')
WHEN #PERIODTYPE = 'M' THEN DATE_FORMAT(R.DATENEW,'%Y-%m')
WHEN #PERIODTYPE = 'Y' THEN DATE_FORMAT(R.DATENEW,'%Y')
ELSE DATE_FORMAT(R.DATENEW,'%Y-%m-%d')
END `Period`,
DATE_FORMAT(MIN(R.DATENEW),'%Y-%m-%d') min_date,
DATE_FORMAT(MAX(R.DATENEW),'%Y-%m-%d') max_date,
COUNT(*) Transactions,
FORMAT(SUM(IFNULL(SQ.`Sold Units`,0)),2) `Sold Units`,
FORMAT(MAX(P.TOTAL), 2) `Largest Order`,
FORMAT(SUM(P.TOTAL), 2) `Total $ Sold`,
FORMAT(SUM(TXL.AMOUNT), 2) `Total Tax $ Collected`
FROM RECEIPTS R INNER JOIN TAXLINES TXL ON R.ID = TXL.RECEIPT
INNER JOIN TAXES TX ON TXL.TAXID = TX.ID
INNER JOIN TAXCATEGORIES TXC ON TX.CATEGORY = TXC.ID
INNER JOIN PAYMENTS P ON P.RECEIPT = R.ID
INNER JOIN TICKETS ON R.ID = TICKETS.ID
-- LEFT JOIN (SELECT TL.TICKET, SUM(TL.UNITS) 'Sold Units' FROM TICKETLINES TL GROUP BY TL.TICKET) SQ ON T.ID = SQ.TICKET
CROSS JOIN (SELECT SUM(TL.UNITS) 'Sold Units' FROM TICKETLINES TL WHERE TICKETS.ID = SQ.TICKET) SQ
GROUP BY CASE
WHEN #PERIODTYPE = 'W' THEN DATE_FORMAT(R.DATENEW,'%u')
WHEN #PERIODTYPE = 'M' THEN DATE_FORMAT(R.DATENEW,'%Y-%m')
WHEN #PERIODTYPE = 'Y' THEN DATE_FORMAT(R.DATENEW,'%Y')
ELSE DATE_FORMAT(R.DATENEW,'%Y-%m-%d')
END
ORDER BY R.DATENEW
The query don't work in mysql beacuse mysql can't use an alias declared ad an upper level respect the subquery ..
in your subquery in Cross Join
CROSS JOIN (SELECT SUM(TL.UNITS) 'Sold Units'
FROM TICKETLINES TL WHERE T.TICKETID = TL.TICKET) SQ
You use T.TICKETID
The alias T
INNER JOIN TICKETS T ON R.ID = T.ID
Is declare in a place not "accessible" by the scope of the subquery ..
Then if is possible i suggest you of build a subquery that non refer to T alias .. Try (if is possible ) building an equivalent subquery wihout alias
Related
I have the next SQL statement:
SELECT
p.ID,
p.TheName0,
(SELECT IFNULL(SUM(att.S_FinalAmount),0) From tbl_groups_classes_att att
INNER JOIN tbl_students st
ON st.ID = att.StudentID
INNER JOIN tbl_groups_classes cls
ON cls.ID = att.ClassID
WHERE st.ParentID = p.ID
and cls.TheDate BETWEEN #Date1 and #Date2
and att.TheStatus <> 'absent'
) as CurrMost,
(SELECT IFNULL(SUM(att.S_FinalAmount),0) From tbl_groups_classes_att att
INNER JOIN tbl_students st
ON st.ID = att.StudentID
INNER JOIN tbl_groups_classes cls
ON cls.ID = att.ClassID
WHERE st.ParentID = p.ID and cls.TheDate< #Date1 and att.TheStatus <> 'absent'
) as PrevMost,
(SELECT IFNULL(SUM(pay.TheAmount),0) From tbl_parents_payments pay Where p.ID = pay.ParentID
AND pay.TheDate BETWEEN #Date1 and #Date2
) as CurrMadf,
(SELECT IFNULL(SUM(pay.TheAmount),0) From tbl_parents_payments pay Where p.ID = pay.ParentID
AND pay.TheDate < #Date1
) as PrevMadf,
(SELECT CurrMost + PrevMost) as AllMost,
(SELECT CurrMadf + PrevMadf) as AllMadf,
(SELECT AllMost - AllMadf) AS FinalTotal
from tbl_parents p
I want to order it by FinalTotal, I tried to put :
from tbl_parents p order by FinalTotal
but it doesn't be affected.
how I can sort it? and please note that I tried many solutions on the internet but without result.
thanks advanced
The fail-safe solution is to place the whole query as a table expression to produce the column name, and then sorting is trivial.
For example:
select *
from (
-- your query here
) x
order by FinalTotal
Here is my query,
SELECT
p.pcode,
p.productName,
s.pcode,
MAX(s.in_stock) AS opening_stock,
SUM(s.soldQty) AS sold_qty,
MIN(s.remaining_qty) AS closing_stock,
s.date_created,
g.pcode,
g.qty,
g.received_qty,
g.received_on
FROM tbl_products p
LEFT JOIN tbl_sold_items s
ON p.pcode = s.pcode
LEFT JOIN tbl_shop_gr_items g
ON p.pcode = g.pcode
WHERE
(s.date_created = '2019-09-27') AND
(g.received_on = '2019-09-27')
GROUP BY p.pcode
stock_report_sample
When the above query is executed it return null values when one of the selected table doesn't have the item id for that particular day. I want it to show a list of all the items(products) available even though the item has not been sold or received so that in those instances it should show zero (0)
Maybe you can use ISNULL to show zero value if NULL
SELECT
p.pcode,
p.productName,
s.pcode,
ISNULL(MAX(s.in_stock),0) AS opening_stock,
ISNULL(SUM(s.soldQty),0) AS sold_qty,
ISNULL(MIN(s.remaining_qty),0) AS closing_stock,
s.date_created,
g.pcode,
g.qty,
g.received_qty,
g.received_on
FROM tbl_products p
LEFT JOIN tbl_sold_items s ON p.pcode = s.pcode
LEFT JOIN tbl_shop_gr_items g ON p.pcode = g.pcode
WHERE(s.date_created = '2019-09-27') AND (g.received_on = '2019-09-27')
GROUP BY p.pcode
SELECT
p.pcode,
p.productName,
CASE
WHEN gr_rows IS NULL AND sl_rows IS NULL THEN 0
WHEN gr_rows > 0 AND sl_rows IS NULL THEN received_stock
WHEN gr_rows > 0 AND sl_rows > 0 THEN opening_stock
ELSE 0
END AS op_stock,
IFNULL(received_stock, 0),IFNULL(sold_stock, 0)
FROM tbl_products p
LEFT JOIN (
SELECT COUNT(r.ID) AS gr_rows,r.pcode,r.received_on,SUM(r.received_qty) AS received_stock
FROM tbl_shop_gr_items r
WHERE r.received_on = '2019-10-03'
GROUP BY r.pcode
)AS r ON p.pcode = r.pcode
LEFT JOIN (
SELECT COUNT(s.ID) AS sl_rows,s.pcode,s.date_created,SUM(s.soldQty) AS sold_stock
FROM tbl_sold_items s
WHERE s.date_created = '2019-10-03'
GROUP BY s.pcode
)AS s ON p.pcode = s.pcode
LEFT JOIN (
SELECT t.ID,t.pcode,t.date_created,t.remaining_qty AS opening_stock
FROM tbl_sold_items t
WHERE t.date_created > '2019-10-03'
GROUP BY t.pcode ORDER BY t.ID
)AS t ON p.pcode = t.pcode
The above code has solved my issue
in the below code there are multiple entries in 'leads' table with the same 'account_id'. I want it to return a single row - the one with the minimal value of another field 'date_entered'. I cannot use 'group by' on account_id as I intend to use 'group by' on BU and get summation accordingly. Please help.
select uc.business_unit_dp_c,
FORMAT(SUM(CASE
WHEN lc.source_leads_c not in ('Discovery','Discovery SuperEmail','Self Generated','Partner','Channel_Partner') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c not in ('Discovery','Discovery SuperEmail','Self Generated','Partner','Channel_Partner') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Online,
FORMAT(SUM(CASE
WHEN lc.source_leads_c in ('Discovery', 'Discovery SuperEmail') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c in ('Discovery', 'Discovery SuperEmail') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Discovery,
FORMAT(SUM(CASE
WHEN lc.source_leads_c in ('Partner','Channel_Partner') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c in ('Partner','Channel_Partner') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Self_Generated_CP
from opportunities as o
left join opportunities_cstm as oc on o.id=oc.id_c
left join opportunities_knw_caf_1_c as ok on o.id=ok.opportunities_knw_caf_1opportunities_ida
left join knw_caf as k on ok.opportunities_knw_caf_1knw_caf_idb=k.id
left join opportunities_knw_sivr_caf_1_c as os on os.opportunities_knw_sivr_caf_1opportunities_ida=o.id
left join knw_sivr_caf as s on s.id=os.opportunities_knw_sivr_caf_1knw_sivr_caf_idb
left join accounts_opportunities as ao on ao.opportunity_id=o.id
left join leads as l on l.account_id=ao.account_id and l.account_id <> ''
left join leads_cstm as lc on lc.id_c=l.id
left join users_cstm as uc on uc.id_c=o.assigned_user_id
where o.sales_stage='clw' and
(k.id<>'' or s.id<>'') and o.jira_raise_date <> '' and
(o.tranjection_type in ('Fresh Plan / New Customer','Number Activation','Revival','Balance Amount') or o.transaction_sivr in ('Paid Project','Number Allocation','New Feature')) and
o.jira_raise_date between '2016-06-01' and curdate()
group by uc.business_unit_dp_c
Write SQL just as you described
Select *
from from opportunities o
left join opportunities_cstm oc
on o.id = oc.id_c
left join opportunities_knw_caf_1_c ok
on o.id = ok.opportunities_knw_caf_1opportunities_ida
left join knw_caf k
on ok.opportunities_knw_caf_1knw_caf_idb = k.id
left join opportunities_knw_sivr_caf_1_c os
on os.opportunities_knw_sivr_caf_1opportunities_ida=o.id
left join knw_sivr_caf s
on s.id = os.opportunities_knw_sivr_caf_1knw_sivr_caf_idb
left join accounts_opportunities ao
on ao.opportunity_id=o.id
left join leads l
on l.account_id=ao.account_id
and l.account_id <> ''
left join leads_cstm lc
on lc.id_c = l.id
left join users_cstm uc
on uc.id_c = o.assigned_user_id
where o.sales_stage = 'clw' and
and (k.id <> '' or s.id <> '')
and o.jira_raise_date <> ''
and (o.tranjection_type in
('Fresh Plan / New Customer',
'Number Activation','Revival','Balance Amount') or
o.transaction_sivr in
('Paid Project','Number Allocation','New Feature'))
and o.jira_raise_date between '2016-06-01' and curdate()
-- next, add this additional predicate to Where clause...
use table w/DateEntered column
and date_entered =
(Select Min(date_entered)
From accounts_opportunities os
join tableWithDateEntered dr -- Table w/DateEntered
on ????? -- proper join criteria here
Where os.account_id = l.account_id)
--- or as constructed by op ( and simplified by me, since both account_id and date_entered are in table leads, that's the only table that needs to be referenced in the subquery).....
and l.date_entered =
(select min(date_entered)
from leads
where account_id = l.account_id)
select min(C.date),C.Customer_Code from (
select InvoiceNo,month(InvoiceDate) as date,Customer_Code,Createddate from tbl_Invoices A Inner Join tbl_customer B on A.customer_Code=B.CustomerCode
where YEAR(InvoiceDate)='2017'
and CustomerCode not in (select CustomerCode from tbl_customer where year(createddate) in (year(getdate())))
and CustomerCode not in (select customer_Code from tbl_Invoices where year(InvoiceDate) in (year(getdate())-1))
and CustomerCode in (select customer_Code from tbl_Invoices where year(InvoiceDate) not in (year(getdate())))
--group by Customer_Code,Createddate,InvoiceNo
)C group by C.Customer_Code
Here is my sp query:
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`#`%` PROCEDURE `USP_GetUserOrders`(UserId INT)
BEGIN
SELECT op.OrderId,
O.Number,
SUM(op.Price) Price,
(SELECT CONCAT(A.Detail, ' ',C.Name, ' / ', Ci.Name) FROM kobiakinlar.Address AS A
INNER JOIN County AS C ON C.CountyId = A.CountyId
INNER JOIN City AS Ci ON C.CityId = Ci.CityId
WHERE UserId = O.UserId) AS UserAddress,
( SELECT CASE WHEN O.Status =0 THEN 'Onay Bekliyor' WHEN O.Status =1 THEN 'Onaylandı' WHEN O.Status = 2 THEN 'Reddedildi' END) Status,
O.Creation,
( SELECT CASE WHEN O.IsDelivered =0 THEN 'Teslim Edilmedi' ELSE 'Teslim Edildi' END) IsDelivered,
group_concat(P.Name) Product
FROM
kobiakinlar.product P
JOIN
kobiakinlar.orderproduct op ON op.ProductId = P.productId
JOIN
kobiakinlar.order O ON O.orderId = op.OrderId
JOIN
kobiakinlar.address A ON A.addressId = O.AddressId
WHERE O.UserId = UserId
GROUP BY op.OrderId;
END
It returns Error Code: 1242. Subquery returns more than 1 row when I CALL USP_GetUserOrders(3)
But I run only sql in query tab, it runs and return what I want. You can see query's result in image:
Do you have any suggestion?
I'm pretty sure the reason is the confusion between UserId and o.UserId.
In the query context, it does not know that you mean the argument to the sp. Change the name of the arguemnt to something like "arg_UserId" and substitute that in the query where appropriate.
You can also simplify your query syntax. The SELECT outside the case statements is redundant. Also, assuming that the joins to County and City are always 1-1, you can rewrite the query as:
SELECT op.OrderId, O.Number, SUM(op.Price) Price,
CONCAT(A.Detail, ' ', C.Name, ' / ', Ci.Name) AS UserAddress,
(CASE WHEN O.Status =0 THEN 'Onay Bekliyor' WHEN O.Status =1 THEN 'Onaylandı' WHEN O.Status = 2 THEN 'Reddedildi' END) Status,
O.Creation,
(CASE WHEN O.IsDelivered =0 THEN 'Teslim Edilmedi' ELSE 'Teslim Edildi' END) IsDelivered,
group_concat(P.Name) as Product
FROM kobiakinlar.product P JOIN
kobiakinlar.orderproduct op
ON op.ProductId = P.productId JOIN
kobiakinlar.order O
ON O.orderId = op.OrderId JOIN
kobiakinlar.address A ON A.addressId = O.AddressId join
County C
ON C.CountyId = A.CountyId join
City AS Ci
ON C.CityId = Ci.CityId
WHERE O.UserId = arg_UserId
GROUP BY op.OrderId;
SELECT p.value AS __color__,
milestone AS __group__,
milestone,
priority,
time AS created,
COUNT(t.id) as 'total open tickets',
SUM(c.value) as 'Total Dev LOE',
SUM(d.value) as 'Total QALOE'
FROM ticket t
LEFT JOIN ticket_custom c ON (t.id = c.ticket AND c.name = 'devloe')
LEFT JOIN ticket_custom d ON (t.id = d.ticket AND d.name = 'qaloe')
LEFT JOIN enum p ON p.name = t.priority AND p.type = 'priority'
WHERE t.milestone = '$MILESTONE'
AND status <> 'closed'
GROUP BY milestone, priority, DATE(FROM_UNIXTIME(time/1000000)) DESC
Then add subquery to return the sum total devloe and qaloe for each priority.
Select p.value AS __color__
, milestone AS __group__
, milestone
, priority
, time AS created
, Count(t.id) as 'total open tickets'
, Sum( Case When c.name = 'devloe' Then c.value End ) As 'Total Dev LOE'
, Sum( Case When c.name = 'qaloe' Then c.value End ) As 'Total QALOE'
, PriorityCounts.Total_Dev_LOE As Priority_Total_QALOE
, PriorityCounts.Total_QALOE As Priority_Total_QALOE
From ticket As t
Left Join ticket_custom As c
On t.id = c.ticket
And c.name In('devloe', 'qaloe')
Left Join enum p
On p.name = t.priority
AND p.type = 'priority'
Join (
Select t1.priority,
, Sum( Case When c1.name = 'devloe' Then c1.value End ) As Total_Dev_LOE
, Sum( Case When c1.name = 'qaloe' Then c1.value End ) As Total_QALOE
From ticket As t1
Left Join ticket_custom As c1
On t1.id = c1.ticket
And c1.name In('devloe', 'qaloe')
Group By t1.priority
) As PriorityCounts
On PriorityCounts.priority = t.priority
Where t.milestone = '$MILESTONE'
And status <> 'closed'
Group By milestone, priority, DATE(FROM_UNIXTIME(time/1000000)) DESC
Doesn't answer your question, but you could simplify the query:
SELECT p.value AS __color__,
milestone AS __group__,
milestone,
priority,
time AS created,
COUNT(t.id) as 'total open tickets',
SUM(CASE WHEN c.name = 'devloe' THEN c.value ELSE 0 END) as 'Total Dev LOE',
SUM(CASE WHEN c.name = 'qaloe' THEN c.value ELSE 0 END) as 'Total QALOE'
FROM TICKET t
LEFT JOIN TICKET_CUSTOM c ON c.ticket = t.id
AND c.name IN ('devloe', 'qaloe')
LEFT JOIN ENUM p ON p.name = t.priority
AND p.type = 'priority'
WHERE t.milestone = '$MILESTONE'
AND status <> 'closed'
GROUP BY milestone, priority, DATE(FROM_UNIXTIME(time/1000000)) DESC