[英]MySQL subquery - using alias from SELECT in WHERE conditions (no CTE)
我試圖找出/如何在下面下調例如實現子查詢。
問題是我需要根據時區添加小時數,然后返回這些字段。
但是,同時,我需要按相同的字段進行過濾,為了准確起見,我需要將它們調整為正確的時區。
能否請您給我一個有關如何解決此問題的建議?
SELECT
od.ID AS 'Id',
CASE WHEN tzp.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredStartTime, INTERVAL 1 HOUR)
ELSE od.declaredStartTime END AS 'Collection date\\time',
CASE WHEN tzd.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredEndTime, INTERVAL 1 HOUR)
ELSE od.declaredEndTime END AS 'Delivery date\\time'
FROM orders od
LEFT OUTER JOIN time_zone AS tzp
ON (tzp.ID = od.pickupTimeZone_ID)
LEFT OUTER JOIN time_zone AS tzd
ON (tzd.ID = od.dropTimeZone_ID)
WHERE
od.IS_DELETED != '1'
-- AND 'Delivery date\\time' >= '2019-06-30' --<< This won't work because
-- AND 'Delivery date\\time' <= '2019-08-01' --<< SELECT is the last operation
不幸的是,我沒有選擇使用CTE,因為我們的MySQL是5.6,而CTE從8.0開始可用
編輯:使代碼示例有效
編輯:命令的完整工作版本
SELECT
od.ID AS 'Id',
od.referenceNumber AS 'Reference number',
od.secondReferenceNumber AS 'Second reference number',
od.status AS 'Status',
ADDDATE(od.created, INTERVAL 1 HOUR) AS 'Creation date/time', -- BST not accounted for!
st.name AS 'Shipment type',
IFNULL(sp.name, '') AS 'Supplier',
ls.name AS 'Collection location',
CASE WHEN tzp.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredStartTime, INTERVAL 1 HOUR)
ELSE od.declaredStartTime END AS 'Collection date\\time',
ld.name AS 'Delivery location',
CASE WHEN tzd.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredEndTime, INTERVAL 1 HOUR)
ELSE od.declaredEndTime END AS 'Delivery date\\time',
od.supplierRate AS 'Supplier rate (pounds)',
IFNULL(od.alternativeSupplierRate, '') AS 'Supplier alternative rate (pounds)',
od.supplierTransportTotal AS 'Supplier total rate (pounds)',
od.customerRate AS 'Customer rate (pounds)',
IFNULL(od.alternativeCustomerRate, '') AS 'Customer alternative rate (pounds)',
od.customerTransportTotal AS 'Customer total rate (pounds)',
IFNULL(od.quantity, '') AS 'Quantity',
IFNULL(od.weight, '') AS 'Weight',
IFNULL(od.palletQuantity, '') AS 'Pallet quantity',
IFNULL(od.kmsTravelled, '') AS 'Kms travelled',
IFNULL(od.carbonFootprint, '') AS 'Carbon footprint',
IFNULL(od.performanceScore, '') AS 'Performance score',
od.fuel_surcharge AS 'Fuel surcharge (pounds)',
od.caf_surcharge AS 'CAF surcharge (pounds)',
IFNULL(od.supplierFuelSurcharge, '') AS 'Supplier fuel surcharge (pounds)',
IFNULL(od.supplierCAFSurcharge, '') AS 'Supplier CAF surcharge (pounds)',
od.vehiclesRegistrationInformation AS 'Vehicles registration information',
od.trailerIsChecked AS 'Trailer is checked',
od.checkedTrailerNumber AS 'Trailer number',
od.additionalPickupsNumber AS 'Number of additional pickups',
od.additionalDropsNumber AS 'Number of additional drops',
IFNULL(od.customerRateFromPricingMatrix, '') AS 'Customer rate from pricing matrix',
IFNULL(od.supplierRateFromPricingMatrix, '') AS 'Supplier rate from pricing matrix',
IF(el.shipmentLateType IS NULL, 'FALSE', 'TRUE') AS 'Is late', -- NULL or late type
IFNULL(rc.name, '') AS 'Late category',
od.comment AS 'Comments',
od.customerComment AS 'Customer comments',
od.supplierComment AS 'Supplier comments',
IF(od.rejectedByCustomer, 'TRUE', 'FALSE') AS 'Rejected by customer', -- dbck
IFNULL(uc.name, '') AS 'Unallocation reason',
IFNULL(us2.name, '') AS 'Unallocation user',
IFNULL(ur.created, '') AS 'Unallocation date/time',
IFNULL(sp2.name, '') AS 'Unallocation supplier',
IFNULL(od.supplierRankPosition, '') AS 'Supplier\'s position',
IFNULL(od.supplierRank, '') AS 'Supplier\'s rank',
IFNULL(od.highestRankOnAllocation, '') AS 'Highest rank',
IF(od.proveOfDelivery IS NULL, 'FALSE', 'TRUE') AS 'POD attached', -- NULL or filename
IFNULL(od.supplierInvoiceNumber, '') AS 'Supplier Sage invoice number',
IFNULL(od.customerInvoiceNumber, '') AS 'Customer Sage invoice number',
IFNULL(od.purchaseOrderNumber, '') AS 'Purchase orders batch number',
IFNULL(vc.name, '') AS 'Vehicle',
IFNULL(od.invoicingKmsTravelled, '0') AS 'Actual Kms travelled',
IFNULL(od.duration, '0') AS 'Actual duration',
IFNULL(vc.location, '') AS 'Vehicle location', -- loc verify
IFNULL(tp.idling, '0') AS 'Idling time',
IFNULL(tp.fuelUsed, '0') AS 'Fuel used',
IF(od.hasDeliveryDiscrepancy, 'TRUE', 'FALSE') AS 'Has delivery discrepancy',
IFNULL(od.deliveryDiscrepancyReasonID, '') AS 'Delivery discrepancy reason Id',
IFNULL(dc1.title, '') AS 'Delivery discrepancy reason name',
IFNULL(od.deliveryDiscrepancyComment, '') AS 'Delivery discrepancy comment',
IF(od.hasHazardousGoods, 'TRUE', 'FALSE') AS 'Has hazardous goods',
IFNULL(od.surchargeReasonId, '') AS 'Surcharge reason Id',
IFNULL(dc2.title, '') AS 'Surcharge reason name',
od.bookingReference AS 'Booking reference',
od.driverName AS 'Driver',
CASE
WHEN ISNULL(wr.passed) THEN 'Not started'
WHEN SUM(CASE WHEN wr.passed=0 THEN 1 ELSE 0 END)=0
THEN 'Passed'
ELSE 'Failed'
END AS 'Walkaround Check status',
SUM(CASE
WHEN wr.passed=0 THEN 1 ELSE 0
END) AS 'Walkaround Check failed count'
FROM orders od
LEFT OUTER JOIN shipment_type AS st
ON (st.ID = od.shipmentType_ID)
LEFT OUTER JOIN shipment_unallocate_reason AS ur
ON (ur.shipment_ID = od.ID)
LEFT OUTER JOIN unallocate_reason_codes AS uc
ON (uc.ID = ur.reasonCode_ID)
LEFT OUTER JOIN user AS us2
ON (us2.ID = ur.user_ID)
LEFT OUTER JOIN suppliers AS sp
ON (sp.ID = od.supplier_ID)
LEFT OUTER JOIN suppliers AS sp2
ON (sp2.ID = ur.supplier_ID)
LEFT OUTER JOIN walk_around_check AS wc
ON (wc.shipment_id = od.ID)
LEFT OUTER JOIN walk_around_check_result AS wr
ON (wr.check_id = wc.ID)
LEFT OUTER JOIN walk_around_check_item AS wi
ON (wr.check_item_id = wi.id)
LEFT OUTER JOIN landmark AS ld
ON (ld.ID = od.destination_id)
LEFT OUTER JOIN landmark AS ls
ON (ls.ID = od.source_id)
LEFT OUTER JOIN landmark AS lw
ON (lw.ID = wc.location_id)
LEFT OUTER JOIN time_zone AS tzp
ON (tzp.ID = od.pickupTimeZone_ID)
LEFT OUTER JOIN time_zone AS tzd
ON (tzd.ID = od.dropTimeZone_ID)
LEFT OUTER JOIN user AS us
ON (us.ID = wc.driver_id)
LEFT OUTER JOIN shipment_event AS el
ON (el.Shipment_ID = od.ID) -- AND se.shipmentLateType = 'DELIVERY_LATE'
LEFT OUTER JOIN late_reason_codes AS rc
ON (rc.ID = el.reasonCode_ID)
LEFT OUTER JOIN dictionary AS dc1
ON (dc1.id = od.deliveryDiscrepancyReasonID)
LEFT OUTER JOIN dictionary AS dc2
ON (dc2.id = od.surchargeReasonId)
LEFT OUTER JOIN trips AS tp
ON (tp.shipment_ID = od.ID)
LEFT OUTER JOIN vehicle AS vc
ON (vc.id = tp.vehicle_ID)
WHERE od.IS_DELETED != '1'
-- NOTE: Have to compare dates incl. timezone changes!!!
-- AND 'Collection date\\time' >= '2019-06-30'
-- AND 'Collection date\\time' <= '2019-08-01'
-- AND 'Delivery date\\time' >= '2019-06-30'
-- AND 'Delivery date\\time' <= '2019-08-01'
GROUP BY od.ID -- required in conjunction with SUM to not return single row
ORDER BY od.ID ASC
您必須在WHERE子句中重復CASE語句:
AND CASE
WHEN tzd.ZoneId='Etc/GMT-1'THEN ADDDATE(od.declaredEndTime, INTERVAL 1 HOUR)
ELSE od.declaredEndTime
END BETWEEN '2019-06-30' AND '2019-08-01'
代替:
AND 'Delivery date\\time' >= '2019-06-30'
AND 'Delivery date\\time' <= '2019-08-01'
這樣做的另一種方法是使用HAVING
子句而不是WHERE
但這將需要將查詢嵌套為子查詢,因為您已經在使用GROUP BY
:
SELECT Id, `Collection date\\time`, `Delivery date\\time`
FROM (
SELECT
od.ID AS 'Id',
CASE WHEN tzp.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredStartTime, INTERVAL 1 HOUR)
ELSE od.declaredStartTime END AS `Collection date\\time`,
CASE WHEN tzd.ZoneId='Etc/GMT-1'
THEN ADDDATE(od.declaredEndTime, INTERVAL 1 HOUR)
ELSE od.declaredEndTime END AS `Delivery date\\time`,
FROM orders od
LEFT OUTER JOIN time_zone AS tzp
ON (tzp.ID = od.pickupTimeZone_ID)
LEFT OUTER JOIN time_zone AS tzd
ON (tzd.ID = od.dropTimeZone_ID)
HAVING
od.IS_DELETED != '1'
AND `Delivery date\\time` >= '2019-06-30' --<< This won't work because
AND `Delivery date\\time` <= '2019-08-01' --<< SELECT is the last operation
)
GROUP....
注意:由於使用了GROUP BY子句,因此這些計算列在選擇列表中的意義是什么? 您的陳述甚至不應運行。 也許這並不是您真正擁有的確切代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.