Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
katethegreat
Starting Member
13 Posts |
Posted - 2012-03-30 : 17:29:45
|
| Hello my esteemed SQL fellows. I've spent the last few days painstakingly putting together the most convoluted, multi-join, multi-union query. I'm happy to say that I've finally got it spitting out the data in a way that it needs to be, but the query itself is incredibly long and repetetive so I'm wondering if there's any way to consolidate/shorten it while still achieving the same ultimate result. Have a look and tell me if I've done something stupid:SELECT o.OrderID, o.OrderDate, o.PaymentAmount, o.CustomerID, o.SalesTax1, (SELECT PaymentMethod FROM PaymentMethods WITH (NOLOCK) WHERE PaymentMethods.PaymentMethodID = o.PaymentMethodID) As PaymentMethod, orderdetails.productcode, orderdetails.ProductPrice, orderdetails.quantity, (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) as shiptypeFROM Orders o WITH (NOLOCK) LEFT JOIN ( SELECT OrderID, productcode, productprice, quantity FROM OrderDetails WITH (NOLOCK) GROUP BY OrderID, productcode, productprice, quantity) OrderDetails ON o.OrderID = OrderDetails.OrderID WHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0AND o.OrderID > 22647UNION ALLSELECT DISTINCTo.OrderID, o.OrderDate, o.PaymentAmount, o.CustomerID, o.SalesTax1, (SELECT PaymentMethod FROM PaymentMethods WITH (NOLOCK) WHERE PaymentMethods.PaymentMethodID = o.PaymentMethodID) As PaymentMethod, 'INSURANCE' As productcode, '4.95' As ProductPrice, '1' As quantity, (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) as shiptypeFROM Orders o WITH (NOLOCK) LEFT JOIN ( SELECT OrderID FROM OrderDetails WITH (NOLOCK) GROUP BY OrderID) OrderDetails ON o.OrderID = OrderDetails.OrderID WHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%INSUR%'AND o.OrderID > 22647UNION ALLSELECT DISTINCTo.OrderID, o.OrderDate, o.PaymentAmount, o.CustomerID, o.SalesTax1, (SELECT PaymentMethod FROM PaymentMethods WITH (NOLOCK) WHERE PaymentMethods.PaymentMethodID = o.PaymentMethodID) As PaymentMethod, 'FedEx' As productcode, totalshippingcost As ProductPrice, '1' As quantity, (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) as shiptypeFROM Orders o WITH (NOLOCK) LEFT JOIN ( SELECT OrderID FROM OrderDetails WITH (NOLOCK) GROUP BY OrderID) OrderDetails ON o.OrderID = OrderDetails.OrderID WHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0AND o.totalshippingcost > 0AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) NOT LIKE '%INSUR%'AND o.OrderID > 22647UNION ALLSELECT DISTINCTo.OrderID, o.OrderDate, o.PaymentAmount, o.CustomerID, o.SalesTax1, (SELECT PaymentMethod FROM PaymentMethods WITH (NOLOCK) WHERE PaymentMethods.PaymentMethodID = o.PaymentMethodID) As PaymentMethod, 'FedEx' As productcode, totalshippingcost-4.95 As ProductPrice, '1' As quantity, (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) as shiptypeFROM Orders o WITH (NOLOCK) LEFT JOIN ( SELECT OrderID FROM OrderDetails WITH (NOLOCK) GROUP BY OrderID) OrderDetails ON o.OrderID = OrderDetails.OrderID WHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0AND o.totalshippingcost > 0AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%INSUR%' AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%FedEx%'AND o.OrderID > 22647ORDER BY o.orderid________Again, the data is EXACTLY how I need it, but I'm wondering if there's a way to shorten this code: more specifically so that I only have to enter a new o.OrderID ONE TIME rather than once per UNION. I look forward to any ideas or suggestions, thanks!Kate the Great |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-03-30 : 17:54:51
|
something like this?I didnt understand last select though you're checking same field for two conditionsAND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%INSUR%' AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%FedEx%'is this correct?SELECT o.OrderID, o.OrderDate, o.PaymentAmount, o.CustomerID, o.SalesTax1, PaymentMethods.PaymentMethod, COALESCE(orderdetails.productcode,CASE WHEN shippingmethodname LIKE '%INSUR%' THEN 'INSURANCE' ELSE 'FedEx' END) AS productcode, COALESCE(orderdetails.ProductPrice,CASE WHEN shippingmethodname LIKE '%INSUR%' THEN '4.95' ELSE totalshippingcost END) AS ProductPrice, COALESCE(orderdetails.quantity,1) AS quantity, shippingmethods.shippingmethodname as shiptypeFROM Orders o WITH (NOLOCK)INNER JOIN PaymentMethods WITH (NOLOCK) ON PaymentMethods.PaymentMethodID = o.PaymentMethodIDLEFT JOIN ( SELECT OrderID, productcode, productprice, quantity FROM OrderDetails WITH (NOLOCK) GROUP BY OrderID, productcode, productprice, quantity) OrderDetails ON o.OrderID = OrderDetails.OrderID LEFT JOIN shippingmethods ON shippingmethods.shippingmethodid = o.shippingmethodidWHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0AND o.OrderID > 22647 ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
|
|
katethegreat
Starting Member
13 Posts |
Posted - 2012-03-31 : 16:56:48
|
quote: Originally posted by visakh16 something like this?I didnt understand last select though you're checking same field for two conditionsAND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%INSUR%' AND (SELECT shippingmethodname FROM shippingmethods WHERE shippingmethods.shippingmethodid = o.shippingmethodid) LIKE '%FedEx%'is this correct?
Hi visakh16 - yeah, I did mean to check the same field for 2 conditions - i just didnt know how to do it properly. What I'm trying to accomplish is this: my shippingmethod name tells me if the customer bought insurance or not, and/or whether or not they paid for fedex. the shippingmethod names are like "INSURED FedDex 2nd Day" or "FedEx 3 Day", so I need a new row for "FedEx" with ONLY the amount the customer paid in fedex, and a new row for "Insurance" with the amount "4.95", so to accomplish that, if the shippingmethodname contains "fedex" and not "insur" then I know that the customer paid for fedex, but not insurance, so there needs to be a row for the "fedex" amount. Then if the the shippingmethodname contains "fedex" AND "insur" then there needs to be a row for Insurance with productprice "4.95" (that is what we charge for insurance) and a row for "fedex" in productcode and productprice is totalshippingcost - 4.95 (the fedex amount only)I tried your code with COALESCE and the "insurance" and "fedex" rows are not in the exported data as they are with my original code. Do you know of a way to make it so the exported data still contains the "fedex" and "insurance" rows without having to update the same conditions multiple times when I want to export new orderids?Thanks!Kate the Great |
 |
|
|
katethegreat
Starting Member
13 Posts |
Posted - 2012-04-07 : 12:35:59
|
| Just thought I'd let you all know that I was able to figure it out. Here's the final code:SELECT o.OrderID, o.OrderDate, o.PaymentAmount, o.BillingFirstName + ' ' + o.BillingLastName + ' ' + CONVERT(varchar(200), o.customerid) As Customer, (SELECT PaymentMethod FROM PaymentMethods WHERE PaymentMethods.PaymentMethodID = o.PaymentMethodID) As PaymentMethod, (SELECT CASE WHEN orderdetails.productprice < 0 THEN 'DISCOUNT' ELSE orderdetails.productcode END) AS productcode, orderdetails.ProductPrice, orderdetails.quantity, o.SalesTax1, shippingmethods.shippingmethodname as shiptype, Coalesce ( (SELECT CASE WHEN shippingmethods.shippingmethodname LIKE '%FedEx%' AND o.shippingmethodid NOT LIKE '10%' THEN o.totalshippingcost ELSE NULL END) , (SELECT CASE WHEN shippingmethods.shippingmethodname LIKE '%FedEx%' AND o.shippingmethodid LIKE '10%' THEN o.totalshippingcost - 4.95 ELSE NULL END) ) AS FedEx, (SELECT CASE WHEN o.shippingmethodid LIKE '10%' THEN '4.95' ELSE '0' END) AS InsuranceFROM Orders oINNER JOIN PaymentMethods ON PaymentMethods.PaymentMethodID = o.PaymentMethodIDLEFT JOIN ( SELECT OrderID, productcode, productprice, Sum(quantity)as quantity FROM OrderDetails GROUP BY OrderID, productcode, productprice, quantity) OrderDetails ON o.OrderID = OrderDetails.OrderID LEFT JOIN shippingmethods ON shippingmethods.shippingmethodid = o.shippingmethodidWHERE 1=1 AND o.OrderStatus <> 'Cancelled' AND o.Total_Payment_Received > 0---Enter the oldest order number you want to downloadAND o.OrderID > 22937Kate the Great |
 |
|
|
jezemine
Master Smack Fu Yak Hacker
2886 Posts |
Posted - 2012-04-07 : 17:45:59
|
It's a little non-standard to use this pattern:, (SELECT CASE WHEN orderdetails.productprice < 0 THEN 'DISCOUNT' ELSE orderdetails.productcode END) AS productcodeYou can remove the select and just do this:, CASE WHEN orderdetails.productprice < 0 THEN 'DISCOUNT' ELSE orderdetails.productcode END AS productcode elsasoft.org |
 |
|
|
katethegreat
Starting Member
13 Posts |
Posted - 2012-04-08 : 09:54:39
|
quote: Originally posted by jezemine It's a little non-standard to use this pattern:, (SELECT CASE WHEN orderdetails.productprice < 0 THEN 'DISCOUNT' ELSE orderdetails.productcode END) AS productcodeYou can remove the select and just do this:, CASE WHEN orderdetails.productprice < 0 THEN 'DISCOUNT' ELSE orderdetails.productcode END AS productcode elsasoft.org
Thank you for the correction, I wasn't sure if I had to do a SELECT on that line or not, and I was so excited that the code worked I wasn't going to mess with it; but (as I'm sure you know) it works just fine with CASE rather than the SELECT. Much appreciated!Kate the Great |
 |
|
|
|
|
|
|
|