SQL Replace with wildcards - sql

I am slowly finding out that the replace string does not work with Wildcards. What I have is approx 10 SKUs, these 10 SKUs each have approx 20 sub SKUs.
Example: _Example - Parent SKU
Example7bTL - Child SKU
-End result would be to turn all child SKUs into _Example so i can get a sum of units sold in a clean format.
what i currently have for reference.
use test
CREATE TABLE #test (
Test int,
BillQty char(300) )
select Quantity, REPLACE (SKU, '%EXAMP%', 'Example') As Sku
from test.dbo.tblSFCOrderTxn
drop table #Test
Raw Data Example---
Quantity SKU
210 EXAMPLE7BOTL-C
42 EXAMPLE4BOTL
30 EXAMPLE1BOTL
28 EXAMPLE12BOTL
100 EXAMPLE7BOTL
97 EXAMPLE4BOTL
29 EXAMPLE7BOTL-C
What I want it to be
Quantity SKU
536 _Example
I am using SQL Server 2012

Given your data, just use case:
select (case when left(sku, 1) = '_' then '_Example' else sku end)

Shouldn't change data just to do a sum(). I would go with:
SELELCT
CASE WHEN SKU LIKE '%EXAMP%' THEN '_Example' ELSE SKU END AS SKU,
SUM(Quantity) AS Quantity
FROM test.dbo.tblSFCOrderTxn
GROUP BY CASE WHEN SKU LIKE '%EXAMP%' THEN '_Example' ELSE SKU END
ORDER BY 1
If you really do want to change the data, it would be:
UPDATE test.dbo.tblSFCOrderTxn
SET SKU = '_Example'
WHERE SKU LIKE '%EXAMP%'

It would be helpful
SELECT SUM(Quantity),'_Example' AS SKU FROM test.dbo.tblSFCOrderTxn GROUP BY CASE SKU WHEN '1' THEN '1' ELSE '2' END

Related

need an additional column in SQL output

I have a table called product_info where there are two columns(product, product_id).There are 5 'product_id' and 10 'product'. I wrote the following code to list products and their count.Now I need to create an additional column called 'favorite_product' if the 'product' count is more than 3.When I tried with a couple of WHERE clause options, it filtered out my existing column (product_count) which I need to keep intact in the output. How can I do that?
Any help would be appreciated.
SELECT product AS Product_Name,
COUNT (product) AS Product_Count
FROM product_info
GROUP BY product
Just use a case expression:
SELECT product AS Product_Name, COUNT(*) AS Product_Count,
(CASE WHEN COUNT(*) > 3 THEN 1 ELSE 0 END) as is_favorite_flag
FROM product_info
GROUP BY product;

Is there a way to substitute GROUP BY

I have two tables i'm working with:
comporder(quantity,cod(Fk on cod(product),cod_ship);
product(cod(Pk),price);
I need to produce a query that will give me the sum of the prices of the products that are in the comporder table for each cod_ship;
I came up with this query:
SELECT sum(p.price),c.cod_ship
FROM product as p JOIN comporder as c
ON(p.cod=c.cod)
GROUP BY c.cod_ship;
However I am not allowed to use the GROUP BY function and I can't seem to have the price where the quanity is above one.
For exampe if in my comporder table I have:
quantity cod cod_ship
2 "1234567890" 27
3 "1234567890" 28
2 "7894561230" 28
1 "5678324515" 28
4 "1234567890" 27
1 "1234567890" 27
And if in my product table I have:
cod price
"1234567890" 20.00
"7894561230" 19.99
"5678324515" 25.99
If I apply my query the result will be:
sum cod_ship
60 27
65.979 28
When te actual result should be, based on the quantity of the products in the table comporder:
sum // cod_ship//
140 // 27//
125,97 //28//
So I can't seem to figure out how to get the sum also based on the quantity of the product and witouth the GROUP BY function, I should just show the sum as "output", can somebody help me out understand how can I do it?
REPLYING TO COMMENTS:
I cannot use group by due to an assignment.
I am using PostgreSQL 12.1
As requested by the OP in the comments here is a solution using GROUP BY:
SELECT SUM(price * quantity) as sum, cod_ship FROM comporders
INNER JOIN products ON products.cod = comporders.cod
GROUP BY cod_ship;
Edit:
Here is the solution without GROUP BY:
SELECT DISTINCT
(
SELECT SUM(price * quantity)
FROM products
INNER JOIN comporders ON products.cod = comporders.cod
WHERE cod_ship = results.cod_ship
) AS sum,
cod_ship
FROM comporders AS results;
It works by first selecting a unique list of cod_ship ids (what we previously grouped the query by).
Then we execute a subquery using the cod_ship id to calculate the sum for each column. We use the table alias results in order to reference the values in the parent query of the subquery.
SQL Fiddle Link
You can do aggregation in subselect like this:
SELECT (
SELECT SUM(p.price)
FROM product AS p
WHERE p.cod = c.cod
) AS price, c.cod_ship
FROM comporder AS c

Determining if a sample contains 0 rows for multiple ID's

So I've created a simple query that will pass all OrdID's that have orders of 2 or more apples:
SELECT ordid
FROM results
WHERE ordid IN (12,24,53,21,41,51)
AND product = 'apples'
GROUP BY ordid
HAVING COUNT(ordid) > 1
How can I do this for OrdID's that contain 0 apples?(This doesn't work as there is no product on the OrdID by apples, so it passes 0 rows.) I'd like it to list all OrdID's that have < 1 products for Apples.
SELECT ordid
FROM results
WHERE ordid IN (12,24,53,21,41,51)
AND product = 'apples'
GROUP BY ordid
HAVING COUNT(ordid) < 1
I cannot reproduce in my machine but I hope that this query should work:
SELECT ordid
FROM results
WHERE ordid in (12,24,53,21,41,51)
GROUP BY ordid
HAVING SUM(CASE WHEN product = 'apples' THEN 1 ELSE 0 END) < 1
I switched the HAVING with a COUNT() of the products instead of the orderid since youre trying to count the number of products.
SELECT ordid
FROM results
WHERE ordid in (12,24,53,21,41,51) and product = 'apples'
GROUP BY ordid
HAVING COUNT(product) = 0
The problem you're running into is that you're selecting FROM a table (i.e., limiting to those rows) where what you want to match is what's not in the table (i.e., excluding those rows). These are opposites.
Instead, flip that around so you're selecting FROM the set of values and then excluding those that match:
SELECT ordid FROM (VALUES (12),(24),(53),(21),(41),(51)) AS ordids(ordid)
WHERE NOT EXISTS (
SELECT * FROM results
WHERE results.ordid = ordids.ordid
AND results.product = 'apples'
)
This will return a result for an ordid even if that value never appears in the results table at all.
Use the EXISTS() function to get all OrdIDs WHERE there does NOT EXIST a correlated row with product = 'apples'

Return a Complete sales order where a given item is purchased SQL

I'm trying to query our Sales_Order_Line_Item table. We are introducing a new "Tariff" Item code, our sales staff are required to add this code to all orders that have items that start with "WI". So I need to create a query that will show me any orders that have item codes that start with "WI" but are missing the "Tariff" code.
I can't seem to figure out how to return a list that shows this data.
For simplicity, my Sales_Order_Line_Item Table has these 3 columns:
UNIQUE_LINE_ID, SALE_ORDER_#, ITEM_#
One dirty trick is to use a case expression and count the number of times these items appear:
SELECT sale_order_no
FROM sales_order_line_item
GROUP BY sale_order_no
HAVING COUNT(CASE WHEN item_code LIKE 'WI%' THEN 1 END) > 0 AND
COUNT(CASE WHEN item_code = 'Tarrif' THEN 1 END) = 0
Should be something like this:
select * from Sales_Order_Line_Item
where ItemCode like 'wi%'
and tariff is null
If, you want full order details you can use EXISTS/NOT EXISTS instead :
select so.*
from sales_order_line_item so
where exists (select 1 from sales_order_line_item sol where sol.sale_order_no = s.sale_order_no and sol.item_code LIKE 'WI%') and
not exists (select 1 from sales_order_line_item sol where sol.sale_order_no = s.sale_order_no and sol.item_code = 'Tarrif');

SQL SUM, Group by and Having query

I have a pretty standard query that will get me a list of products that have stock above 0.
This works fine, however I now need to ADD the SUM of all negative numbers for BranchID 31 for the given SKU.
SELECT * FROM Products WHERE
PrimaryPLU IN
(select SKU FROM Stock
WHERE BranchID IN (2,12,1,11,0,96,32,13,14,15)
AND ApplicationID = #site
GROUP BY SKU HAVING(SUM(Stock)) > 0))
SO BranchID 31 can have positive and negative numbers, however I just need to get the sum of the negative ones for the SKU, this then needs to be added to the check to see if it's over 0.
Not a clue where to start, was hoping for support from a SQL master!
Thanks in advance!
Dave
Try this:
SELECT * FROM Products WHERE
PrimaryPLU IN
(select SKU FROM Stock
WHERE BranchID IN (2,12,1,11,0,96,31,32,13,14,15)
AND ApplicationID = #site
GROUP BY SKU HAVING(SUM(CASE WHEN Stock < 0 AND BranchID = 31
THEN Stock ELSE 0 END)) > 0))
Take the sum of absolute value of the negative numbers (stock) to see if they are non-zero.