SQL ORACLE Problems with three queries - sql

I have three tables orders, orderdetails and customers.
The orders table has these columns:
ORDERID, CUSTOMERID, EMPLOYEEID, TERRITORYID,
ORDERDATE, REQUIREDDATE, SHIPPEDDATE,
SHIPVIA, FREIGHT, SHIPNAME,
SHIPADDRESS, SHIPCITY, SHIPREGION,
SHIPPOSTALCODE, SHIPCOUNTRY
The orderdetails table has these columns:
ORDERID, PRODUCTID, UNITPRICE, QUANTITY, DISCOUNT
And the customers table has these columns:
CUSTOMERID, COMPANYNAME, CONTACTNAME,
CONTACTTITLE, ADDRESS, CITY, REGION,
POSTALCODE, COUNTRY, PHONE, FAX
I have to do three queries:
1 List of orders with a higher total amount (unitprice * quantity * (1 - discount)) provided that the total amount is greater than 10000
I did it like this:
SELECT orderid
FROM orders
JOIN orderdetails USING (orderid)
GROUP BY orderid
HAVING SUM (unitprice * quantity * (1 - discount)) > 10000;
2 Order with the highest total amount (including discount)
I did it like this:
SELECT MAX (orderid),
SUM (unitprice * quantity * (1 - discount)) as price
FROM orders
JOIN orderdetails USING (orderid)
ORDER BY price DESC;
3 show the customerid and the freight (transport) of the customers who have spent more than 2000 freight on all their orders
I have not been able to do this
SELECT customerid,freight
FROM customers
JOIN orders USING (customerid)
HAVING Count (freight) > 2000;
I want to know if I did #1 and #2 correctly or is there a better way to do it and how can I solve #3.
Thank you very much to all.

You don't need the customers table (since the orders table contains both freight and customerid) and need to have a GROUP BY clause and aggregate the freight column in the SELECT clause (and probably want to use SUM rather than COUNT but you haven't provided any sample data so it is difficult to tell):
SELECT customerid,
SUM(freight)
FROM orders
GROUP BY
customerid
HAVING SUM(freight) > 2000;

With Sample data like here:
WITH
orders (ORDERID, CUSTOMERID, EMPLOYEEID, TERRITORYID, ORDERDATE, REQUIREDDATE, SHIPPEDDATE, SHIPVIA, FREIGHT, SHIPNAME,
SHIPADDRESS, SHIPCITY, SHIPREGION, SHIPPOSTALCODE, SHIPCOUNTRY) AS
(
Select 101, 1, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 1500, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 102, 1, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 250, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 103, 1, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 500, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 104, 2, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 750, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 105, 2, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 950, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 106, 2, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 1250, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 107, 3, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 2500, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 108, 4, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 850, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 109, 4, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 950, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual Union All
Select 110, 5, 11, 'T1', DATE '2023-01-03', DATE '2023-01-24', DATE '2023-01-04', 'via A', 1150, 'A SHIP', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY' From Dual
),
details (ORDERID, PRODUCTID, UNITPRICE, QUANTITY, DISCOUNT) AS
(
Select 101, 1001, 700, 5, 0.1 From Dual Union All
Select 101, 1002, 700, 5, 0.1 From Dual Union All
Select 102, 1003, 800, 2, 0.1 From Dual Union All
Select 102, 1004, 700, 2, 0.1 From Dual Union All
Select 103, 1003, 900, 5, 0.3 From Dual Union All
Select 103, 1004, 700, 6, 0.1 From Dual Union All
Select 103, 1005, 700, 7, 0.1 From Dual Union All
Select 104, 1001, 700, 1, 0.1 From Dual Union All
Select 104, 1002, 900, 1, 0.2 From Dual Union All
Select 105, 1002, 900, 3, 0.1 From Dual Union All
Select 106, 1005, 700, 1, 0.1 From Dual Union All
Select 107, 1003, 700, 7, 0.1 From Dual Union All
Select 108, 1004, 700, 8, 0.2 From Dual Union All
Select 109, 1003, 900, 8, 0.1 From Dual Union All
Select 109, 1004, 900, 9, 0.3 From Dual Union All
Select 110, 1005, 700, 9, 0.1 From Dual
),
customers(CUSTOMERID, COMPANYNAME, CONTACTNAME, CONTACTTITLE, ADDRESS, CITY, REGION, POSTALCODE, COUNTRY, FAX) AS
(
Select 1, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual Union All
Select 2, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual Union All
Select 3, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual Union All
Select 4, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual Union All
Select 5, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual Union All
Select 6, 'A COMPANY', 'A CONTACT', 'A TITLE', 'Address 1', 'A CITY', 'A REGION', 'A ZIP', 'A COUNTRY', 'A FAX' From Dual
)
your 3 answers would be like below:
-- 1.
SELECT ORDERID, Sum(UNITPRICE * QUANTITY * (1 - DISCOUNT)) "TOTAL_10K_PLUS"
FROM orders
JOIN details USING (ORDERID)
GROUP BY ORDERID
HAVING SUM (UNITPRICE * QUANTITY * (1 - DISCOUNT)) > 10000;
/*
ORDERID TOTAL_10K_PLUS
---------- --------------
109 12150
103 11340
*/
-- 2. Changed
SELECT ORDERID, TOTAL "HIGHEST_TOTAL"
FROM
( SELECT o.ORDERID,
MAX(SUM(UNITPRICE * QUANTITY * (1 - DISCOUNT))) OVER(Partition By o.ORDERID) as TOTAL
FROM orders o JOIN details d ON (d.ORDERID = o.ORDERID)
GROUP BY o.ORDERID
ORDER BY TOTAL DESC
)
WHERE ROWNUM = 1
/*
ORDERID HIGHEST_TOTAL
---------- -------------
109 12150
*/
-- 3. Changed
SELECT CUSTOMERID, Sum(FREIGHT) "TOTAL_FREIGHT"
FROM orders
GROUP BY CUSTOMERID
HAVING Sum(FREIGHT) > 2000;
/*
CUSTOMERID TOTAL_FREIGHT
---------- -------------
1 2250
2 2950
3 2500
*/

Related

Find the correct matching record from multiple row using TSQL

I am shredding a XML file which contains different types of questions and their answers. I shredded it into a temp table and but got stuck for TickBox type of questions where the correct answer in different XML node and the options are in different nodes.
As shown in below screenshot, I shredded the XML into the table structure shown.
ID = 560 is TickBoxQuestion and the question you can see under column Value.
This TickBoxQuestion has 5 Multiple options from ID = 541 to 554 and the answer is under NodeName = Text. Note the NodeName = Value(1,2,3,4,5) are the OptionID's for these options which are under NodeName = Text.
The correct answer is listed in ID = 559 and Value = 3 which point to the OptionId under NodeName = Value = 3 so the answer is Value = 'Refinanced by a different adviser at a different firm'
Here is the sample data
CREATE TABLE dbo.Sample1
(
ID int,
ParentName varchar(1000),
ParentPosition int,
depth int,
NodeName varchar(1000),
Value varchar(1000),
FullPath varchar(1000),
XPath varchar(1000)
)
INSERT INTO Sample1 (ID, ParentName, ParentPosition, depth, NodeName, Value, FullPath, XPath)
SELECT 541, 'ListOption', 1, 7, 'Text', 'Term expired and loan paid off in full', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[1]/Text[1]' UNION ALL
SELECT 542, 'ListOption', 1, 7, 'Value', '1', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[1]/Value[1]' UNION ALL
SELECT 544, 'ListOption', 2, 7, 'Text', 'Refinanced by the same adviser', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[2]/Text[1]' UNION ALL
SELECT 545, 'ListOption', 2, 7, 'Value', '2', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[2]/Value[1]' UNION ALL
SELECT 547, 'ListOption', 3, 7, 'Text', 'Refinanced by a different adviser at a different firm', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[3]/Text[1]' UNION ALL
SELECT 548, 'ListOption', 3, 7, 'Value', '3', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[3]/Value[1]' UNION ALL
SELECT 550, 'ListOption', 4, 7, 'Text', 'Repaid early from own funds', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[4]/Text[1]' UNION ALL
SELECT 551, 'ListOption', 4, 7, 'Value', '4', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[4]/Value[1]' UNION ALL
SELECT 553, 'ListOption', 5, 7, 'Text', 'Still Active', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[5]/Text[1]' UNION ALL
SELECT 554, 'ListOption', 5, 7, 'Value', '5', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Options[1]/ListOption[5]/Value[1]' UNION ALL
SELECT 559, 'StringListAnswer', 1, 6, 'string', '3', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/StringListAnswer/string', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/StringListAnswer[1]/string[1]' UNION ALL
SELECT 560, 'TickBoxListQuestion', 1, 5, 'Text', 'What has happened to the loan or mortgage?', 'ArrayOfSection/Section/Elements/TickBoxListQuestion/Text', 'ArrayOfSection[1]/Section[1]/Elements[1]/TickBoxListQuestion[1]/Text[1]' UNION ALL
SELECT 757, 'ListOption', 1, 7, 'Text', 'A director of the Firm', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[1]/Text[1]' UNION ALL
SELECT 758, 'ListOption', 1, 7, 'Value', '1', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[1]/Value[1]' UNION ALL
SELECT 760, 'ListOption', 2, 7, 'Text', 'A manager of the Firm', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[2]/Text[1]' UNION ALL
SELECT 761, 'ListOption', 2, 7, 'Value', '2', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[2]/Value[1]' UNION ALL
SELECT 763, 'ListOption', 3, 7, 'Text', 'Employed/engaged by the Firm', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[3]/Text[1]' UNION ALL
SELECT 764, 'ListOption', 3, 7, 'Value', '3', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[3]/Value[1]' UNION ALL
SELECT 766, 'ListOption', 4, 7, 'Text', 'Directly or indirectly receiving a profit or payment or other benefit from the Firm', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[4]/Text[1]' UNION ALL
SELECT 767, 'ListOption', 4, 7, 'Value', '4', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[4]/Value[1]' UNION ALL
SELECT 769, 'ListOption', 5, 7, 'Text', 'The owner/a part-owner/a shareholder in the Firm or any related entity', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[5]/Text[1]' UNION ALL
SELECT 770, 'ListOption', 5, 7, 'Value', '5', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[5]/Value[1]' UNION ALL
SELECT 772, 'ListOption', 6, 7, 'Text', 'Acting as auditor/appointed actuary of the Firm or for any related entity', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[6]/Text[1]' UNION ALL
SELECT 773, 'ListOption', 6, 7, 'Value', '6', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[6]/Value[1]' UNION ALL
SELECT 775, 'ListOption', 7, 7, 'Text', 'No relation to the Firm', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[7]/Text[1]' UNION ALL
SELECT 776, 'ListOption', 7, 7, 'Value', '7', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Options/ListOption/Value', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Options[1]/ListOption[7]/Value[1]' UNION ALL
SELECT 781, 'StringListAnswer', 1, 6, 'string', '7', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/StringListAnswer/string', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/StringListAnswer[1]/string[1]' UNION ALL
SELECT 782, 'FirmInvolvementTickBoxListQuestion', 1, 5, 'Text', 'With respect to the Firm you are claiming for have you, your spouse or partner or a relative of either of you ever been any of the following?', 'ArrayOfSection/Section/Elements/FirmInvolvementTickBoxListQuestion/Text', 'ArrayOfSection[1]/Section[2]/Elements[1]/FirmInvolvementTickBoxListQuestion[1]/Text[1]'
I want to pivot and get the desired output as shown below
I am using SQL Server 2019.
Thanks

Oracle sql using previous rows data in calculations

I have a table T1 with 06 columns and want to get new two columns using a select query.
Here's T1 with two extra columns (STOCK, WAUC) that i want to get :
CREATE TABLE T1 (MOUVEMENT NUMBER(2), OPERATION VARCHAR2(5), ITEM VARCHAR2(5), INPUT_QTY NUMBER(6, 2), OUTPUT_QTY NUMBER(6, 2), INPUT_PRICE NUMBER(6, 2), STOCK NUMBER(6, 2), WAUC NUMBER(6, 2));
INSERT ALL
INTO T1 VALUES(1, 'I', 'A', 1500, 0, 5, 1500, 5)
INTO T1 VALUES(2, 'I', 'A', 700, 0, 6, 2200, 5.31)
INTO T1 VALUES(3, 'O', 'A', 0, 800, 0, 1400, 5.31)
INTO T1 VALUES(4, 'I', 'A', 1000, 0, 5, 2400, 5.18)
INTO T1 VALUES(5, 'O', 'A', 0, 500, 0, 1900, 5.18)
INTO T1 VALUES(6, 'I', 'A', 1000, 0, 7, 2900, 5.8 )
INTO T1 VALUES(7, 'I', 'A', 2000, 0, 7, 4900, 6.28)
INTO T1 VALUES(8, 'I', 'A', 5000, 0, 7, 5400, 6.34)
INTO T1 VALUES(9, 'O', 'A', 0, 1000, 0, 4400, 6.34)
INTO T1 VALUES(10, 'I','A', 1000, 0, 5, 5400, 6.09)
SELECT 1 FROM DUAL;
WAUC is like weighted average unit cost to valorise our stock.
In case first record : STOCK = INPUT and WAUC = INPUT_PRICE;
In case new INPUT operation : new WAUC should be : (last generated WAUC * last generated stock) + (current INPUT * current INPUT_PRICE)) / current generated STOCK.
Ex for 2nd row : WAUC = ((5 * 1500) + (700 * 6)) / 2200 = 5.31
In case new OUTPUT operation : WAUC should be last generated WAUC.
Ex for 3rd row : WAUC = last generated WAUC (5.31) of the same ITEM A.
Means, WAUC should be changed every new INPUT operation.
In my opinion, STOCK and WAUC should be generated on the fly, not as records,
besause otherwise, only one accidently wrong INPUT_PRICE, will cause wrong next WAUC(s) -> wrong next calculation(s) -> (wrong work).
how can I achieve this?
Thanks in advance.
Your logic is textbook example of need for model clause and can be rewritten to that clause almost as you verbosely specified (note the model clause is a beast, to learn more about it see here or here or here):
with t1 (mouvement, operation, item, input_qty, output_qty, input_price, stock_expected, wauc_expected) as (
select 1, 'I', 'A', 1500, 0, 5, 1500, 5 from dual union all
select 2, 'I', 'A', 700, 0, 6, 2200, 5.31 from dual union all
select 3, 'O', 'A', 0, 800, 0, 1400, 5.31 from dual union all
select 4, 'I', 'A', 1000, 0, 5, 2400, 5.18 from dual union all
select 5, 'O', 'A', 0, 500, 0, 1900, 5.18 from dual union all
select 6, 'I', 'A', 1000, 0, 7, 2900, 5.8 from dual union all
select 7, 'I', 'A', 2000, 0, 7, 4900, 6.28 from dual union all
select 8, 'I', 'A', 500, 0, 7, 5400, 6.34 from dual union all
select 9, 'O', 'A', 0, 1000, 0, 4400, 6.34 from dual union all
select 10, 'I','A', 1000, 0, 5, 5400, 6.09 from dual
)
select * from (
select t1.*, 0 as stock_actual, 0 as wauc_actual from t1
)
model
dimension by (row_number() over (order by mouvement) as rn)
measures (mouvement, operation, item, input_qty, output_qty, input_price, stock_expected, wauc_expected, stock_actual, wauc_actual)
rules (
stock_actual[any] = coalesce(stock_actual[cv(rn) - 1], 0) + case operation[cv(rn)]
when 'I' then input_qty[cv(rn)]
when 'O' then -output_qty[cv(rn)]
end,
wauc_actual[any] = case
when cv(rn) = 1
then input_price[cv(rn)]
when operation[cv(rn)] = 'I'
then trunc((wauc_actual[cv(rn) - 1] * stock_actual[cv(rn) - 1] + input_qty[cv(rn)] * input_price[cv(rn)]) / stock_actual[cv(rn)], 2)
when operation[cv(rn)] = 'O'
then wauc_actual[cv(rn) - 1]
end
)
order by mouvement
(I changed typo in operation=5000->500 for mouvement=8 and added truncation to 2 digits - both I guessed from your expected results.)
Db fiddle here.
Note that simple analytic functions are not sufficient for computation of wauc because they have access only to previous values of column of input dataset, not the values of column being computed by the function itself. For stock it would be possible using running totals of sum(input_qty) over (order by mouvement) - sum(output_qty) over (order by mouvement) but for wauc there is hardly any explicit formula.

Select rows which does not have sum equals to zero

I have two tables: #temptable_1 and #temptable_2. I need to select rows which do not have rows in another table that can be subtracted. Let me clarify:
Row with column "Code" with "Code 1" has a "Price" that has value "-2000". Row with column "Code 4" has a "Price" that has value "2000".
It means that if we sum this columns, then the Sum will be zero. So these both rows
should not be selected.
Row with column "Code" with "Code 2" has a "Amount" that has value "-10780.56". Row with column "Code 5" has a "Amount" that has value "10780.56".
It means that if we sum this columns, then the Sum will be zero. So these both rows
should not be selected.
Row with column "Code" with "Code 3" has a "AmountIncVAT" that has value "-12936.67". Row with column "Code 6" has a "AmountIncVAT" that has value "12936.67". It means that if we sum this columns, then the Sum will be zero. So these both rows
should not be selected.
Row with column "Code" with "Code 7" should be in the select result because it cannot be summed with other columns of temptable_1
So, columns that can be summed are: Price, VAT, Amount, AmountIncVAT
Tables looks like this:
DROP TABLE IF EXISTS #temptable_1
CREATE TABLE #temptable_1 ( [Name] varchar(10), [Code] varchar(50), [id_Car] int, [PositionName] varchar(1000),
[Count] decimal(18,3), [id_Unit] int, [Price] decimal(15,2), [VAT] decimal(15,2),
[Amount] decimal(15,2), [AmountIncVAT] decimal(15,2))
INSERT INTO #temptable_1
VALUES
( '1', 'Code 1', 632324, 'Position 1', 1.000, 1036, -2000.00, -401.00, 2001.00, 2401.00),
( '2', 'Code 2', 632324, 'Position 2', 1.000, 1036, -10780.56, -2156.11, -10780.56, 10.67),
( '3', 'Code 3', 632324, 'Position 3', 1.000, 1036, -18780.56, -1, 558.56, -12936.67)
DROP TABLE IF EXISTS #temptable_2
CREATE TABLE #temptable_2 ( [Name] varchar(10), [Code] varchar(50), [id_Car] int, [PositionName] varchar(1000),
[Count] decimal(18,3), [id_Unit] int, [Price] decimal(15,2), [VAT] decimal(15,2),
[Amount] decimal(15,2), [AmountIncVAT] decimal(15,2))
INSERT INTO #temptable_2
VALUES
( '4', 'Code 4', 632324, 'Position 4', 1.000, 1036, 2000.00, 402.00, 3001.00, 8101.00),
( '5', 'Code 5', 632324, 'Position 5', 1.000, 1036, 11780.56, 2156.11, 10780.56, 18936.67),
( '6', 'Code 6', 632324, 'Position 6', 1.000, 1036, 10580.56, 3, -21780.56, 12936.67),
( '7', 'Code 7', 632324, 'Position 7', 8.000, NULL, 415.34, 664.54, 3322.72, 3987.26)
The desired result is one row with "Code 7":
7 Code 6 632324 Position 6 8.000 NULL 415.34 664.54 3322.72 3987.26
I have written the following code:
SELECT
*
FROM
(
SELECT
COUNT(1) OVER (PARTITION BY ABS(q.Price) ORDER BY ABS(q.Price)) as CountByPrice
, COUNT(1) OVER (PARTITION BY ABS(q.Vat) ORDER BY ABS(q.Vat)) as CountByVat
, COUNT(1) OVER (PARTITION BY ABS(q.Amount) ORDER BY ABS(q.Amount)) as CountByAmount
, COUNT(1) OVER (PARTITION BY ABS(q.AmountIncVAT) ORDER BY ABS(q.AmountIncVAT)) as CountByAmountIncVat
, q.*
FROM
(
SELECT * FROM #temptable_1
UNION ALL
SELECT * FROM #temptable_2
) AS q
) AS q1
WHERE q1.CountByPrice =1 AND q1.CountByVat =1 AND q1.CountByAmount = 1 AND q1.CountByAmountIncVat = 1
Is it possible to write this code shorter?
WITH
-- your input
temptable_1(Name,Code,id_Car,PositionName,Count,id_Unit,Price,VAT,Amount,AmountIncVAT)
AS (
SELECT '1', 'Code 1', 632324, 'Position 1', 1.000, 1036, -2000.00, -401.00, 2001.00, 2401.00
UNION ALL SELECT '2', 'Code 2', 632324, 'Position 2', 1.000, 1036, -10780.56, -2156.11, -10780.56, 10.67
UNION ALL SELECT '3', 'Code 3', 632324, 'Position 3', 1.000, 1036, -18780.56, -1, 558.56, -12936.67
)
,
temptable_2 ( Name , Code , id_Car , PositionName , Count , id_Unit , Price , VAT , Amount , AmountIncVAT)
AS (
SELECT'4', 'Code 4', 632324, 'Position 4', 1.000, 1036, 2000.00, 402.00, 3001.00, 8101.00
UNION ALL SELECT'5', 'Code 5', 632324, 'Position 5', 1.000, 1036, 11780.56, 2156.11, 10780.56, 18936.67
UNION ALL SELECT'6', 'Code 6', 632324, 'Position 6', 1.000, 1036, 10580.56, 3, -21780.56, 12936.67
UNION ALL SELECT'7', 'Code 7', 632324, 'Position 7', 8.000, NULL, 415.34, 664.54, 3322.72, 3987.26
)
-- your input ends here. Real query starts here, replace comma with WITH
,
botht AS (
SELECT * FROM temptable_1
UNION ALL
SELECT * FROM temptable_2
)
SELECT
*
FROM botht b
WHERE NOT EXISTS(
SELECT 1 FROM botht c WHERE b.price = c.price * -1
)
AND NOT EXISTS(
SELECT 1 FROM botht c WHERE b.amount = c.amount * -1
)
AND NOT EXISTS(
SELECT 1 FROM botht c WHERE b.amountIncVAT = c.amountIncVAT * -1
)
;
-- out Name | Code | id_Car | PositionName | Count | id_Unit | Price | VAT | Amount | AmountIncVAT
-- out ------+--------+--------+--------------+-------+---------+--------+--------+---------+--------------
-- out 7 | Code 7 | 632324 | Position 7 | 8.000 | | 415.34 | 664.54 | 3322.72 | 3987.26

Getting "column ambiguously defined" without any join in code

I get "column ambiguously defined" error while trying to execute following script:
INSERT INTO experience (id_, company, start_, end_, usr, position_)
WITH exp_ AS (
SELECT 0, 0, DATE'2013-04-30', NULL, 11, 'CEO' FROM DUAL UNION ALL
SELECT 1, 0, DATE'2011-12-11', DATE'2013-04-30', 9, 'Administrator' FROM DUAL UNION ALL
SELECT 2, 0, DATE'2013-04-30', DATE'2015-10-27', 6, 'Manager' FROM DUAL UNION ALL
SELECT 3, 1, DATE'2014-11-04', NULL, 10, 'CEO' FROM DUAL UNION ALL
SELECT 4, 1, DATE'2017-06-13', NULL, 13, 'CTO' FROM DUAL UNION ALL
SELECT 5, 1, DATE'2010-04-22', DATE'2018-10-22', 1, 'Manager' FROM DUAL UNION ALL
SELECT 6, 1, DATE'2019-08-26', NULL, 2, 'Trainer' FROM DUAL UNION ALL
SELECT 7, 1, DATE'2006-02-27', DATE'2016-11-30', 6, 'Video Creator' FROM DUAL UNION ALL
SELECT 8, 2, DATE'2012-04-30', DATE'2013-11-24', 5, 'CEO' FROM DUAL UNION ALL
SELECT 9, 2, DATE'2013-01-10', NULL, 0, 'CEO' FROM DUAL UNION ALL
SELECT 10, 2, DATE'2010-11-01', DATE'2017-01-01', 7, 'Video Creator' FROM DUAL UNION ALL
SELECT 11, 2, DATE'2010-10-03', DATE'2018-03-01', 8, 'Commentator' FROM DUAL
)
SELECT * FROM exp_;
I don't use any JOIN here, and the error description says, that it's caused by trying to join two tables with overlapping column's names.
So why I got it here and how to fix it?
This syntax would work only if you drop the CTE and directly insert the rows with UNION ALL:
INSERT INTO experience (id_, company, start_, end_, usr, position_)
SELECT 0, 0, DATE'2013-04-30', NULL, 11, 'CEO' FROM DUAL UNION ALL
SELECT 1, 0, DATE'2011-12-11', DATE'2013-04-30', 9, 'Administrator' FROM DUAL UNION ALL
SELECT 2, 0, DATE'2013-04-30', DATE'2015-10-27', 6, 'Manager' FROM DUAL UNION ALL
SELECT 3, 1, DATE'2014-11-04', NULL, 10, 'CEO' FROM DUAL UNION ALL
SELECT 4, 1, DATE'2017-06-13', NULL, 13, 'CTO' FROM DUAL UNION ALL
SELECT 5, 1, DATE'2010-04-22', DATE'2018-10-22', 1, 'Manager' FROM DUAL UNION ALL
SELECT 6, 1, DATE'2019-08-26', NULL, 2, 'Trainer' FROM DUAL UNION ALL
SELECT 7, 1, DATE'2006-02-27', DATE'2016-11-30', 6, 'Video Creator' FROM DUAL UNION ALL
SELECT 8, 2, DATE'2012-04-30', DATE'2013-11-24', 5, 'CEO' FROM DUAL UNION ALL
SELECT 9, 2, DATE'2013-01-10', NULL, 0, 'CEO' FROM DUAL UNION ALL
SELECT 10, 2, DATE'2010-11-01', DATE'2017-01-01', 7, 'Video Creator' FROM DUAL UNION ALL
SELECT 11, 2, DATE'2010-10-03', DATE'2018-03-01', 8, 'Commentator' FROM DUAL
See the demo.
You columns do not have names in the CTE. Define it with names:
WITH exp_(id_, company, start_, end_, usr, position_) AS (
Here is a db<>fiddle.
You need to give aliases to your columns. It is enough to do it in the first unioned subquery:
INSERT INTO experience (id_, company, start_, end_, usr, position_)
WITH exp_ AS (
SELECT
0 id_,
0 company,
DATE'2013-04-30' start_,
NULL end_,
11 usr,
'CEO' position
FROM DUAL UNION ALL
SELECT 1, 0, DATE'2011-12-11', DATE'2013-04-30', 9, 'Administrator' FROM DUAL UNION ALL
SELECT 2, 0, DATE'2013-04-30', DATE'2015-10-27', 6, 'Manager' FROM DUAL UNION ALL
SELECT 3, 1, DATE'2014-11-04', NULL, 10, 'CEO' FROM DUAL UNION ALL
SELECT 4, 1, DATE'2017-06-13', NULL, 13, 'CTO' FROM DUAL UNION ALL
SELECT 5, 1, DATE'2010-04-22', DATE'2018-10-22', 1, 'Manager' FROM DUAL UNION ALL
SELECT 6, 1, DATE'2019-08-26', NULL, 2, 'Trainer' FROM DUAL UNION ALL
SELECT 7, 1, DATE'2006-02-27', DATE'2016-11-30', 6, 'Video Creator' FROM DUAL UNION ALL
SELECT 8, 2, DATE'2012-04-30', DATE'2013-11-24', 5, 'CEO' FROM DUAL UNION ALL
SELECT 9, 2, DATE'2013-01-10', NULL, 0, 'CEO' FROM DUAL UNION ALL
SELECT 10, 2, DATE'2010-11-01', DATE'2017-01-01', 7, 'Video Creator' FROM DUAL UNION ALL
SELECT 11, 2, DATE'2010-10-03', DATE'2018-03-01', 8, 'Commentator' FROM DUAL
)
SELECT * FROM exp_;
For your use case, you could also consider using the insert all syntax, which avoids the multiple union alls:
insert all
into experience (id_, company, start_, end_, usr, position_)
values(0, 0, date '2013-04-30', null, 11, 'CEO')
into experience (id_, company, start_, end_, usr, position_)
values(1, 0, date '2011-12-11', date '2013-05-30', 9, 'Administrator')
...
select 1 from dual

How to select rows where one column value is the same on separate dates without using variables?

I have a DB Fiddle as an example: https://www.db-fiddle.com/f/vX7yFVk8j6FPTSm2QVoPNE/2
I'm trying to figure out how to find all bookings for a guest who has booked one room several times on different dates. I can't use a static value/variable like bookings.check_in_date = '2018-03-05', bookings.guest_id = 001 or use subqueries.
I tried:
SELECT bookings.guest_id, bookings.room_number, bookings.check_in_date, bookings.check_out_date
FROM bookings
GROUP BY bookings.guest_id, bookings.room_number, bookings.check_in_date, bookings.check_out_date
HAVING count(distinct bookings.check_in_date) >= 2;
However, it isn't giving me the result I'm looking for but rather I'm looking for this as a result:
guest_id, room_number, check_in_date, check_out_date
1, 203, 2018-03-01T00:00:00.000Z, 2018-03-07T00:00:00.000Z
1, 203, 2018-03-14T00:00:00.000Z, 2018-03-21T00:00:00.000Z
Schema (PostgreSQL v10.0)
CREATE TABLE guests (
id integer,
name text,
address text,
city text,
state text,
postal_code integer,
phone_number numeric(10)
);
CREATE TABLE rooms (
room_number integer,
floor_number integer,
view boolean,
bed_type text
);
CREATE TABLE bookings (
id integer,
guest_id integer,
room_number integer,
order_date date,
check_in_date date,
check_out_date date
);
INSERT INTO guests (id, name, address, city, state, postal_code, phone_number)
VALUES
(1, 'John', '5 8th Avenue', 'New York', 'New York', 10001, 2021110190),
(2, 'Jane', '13 Wall St', 'New York', 'New York', 10001, 1112020190),
(3, 'Jim', '12 Water St', 'New York', 'New York', 10001, 3332224444),
(4, 'Fang', '12 Broadway', 'New York', 'New York', 10001, 1234567890),
(5, 'Bruce', '123 1st Ave', 'New York', 'New York', 10001, 9871112222);
INSERT INTO rooms (room_number, floor_number, view, bed_type)
VALUES
(101, 1, FALSE, 'King'),
(102, 1, FALSE, 'Queens'),
(203, 2, FALSE, 'Queens'),
(204, 2, TRUE, 'King'),
(409, 4, TRUE, 'King');
INSERT INTO bookings (id, guest_id, room_number, order_date, check_in_date, check_out_date)
VALUES
(18001, 001, 203, '2018-03-05', '2018-03-01', '2018-03-07'),
(18002, 001, 203, '2018-03-05', '2018-03-14', '2018-03-21'),
(18003, 001, 409, '2018-03-05', '2018-11-27', '2018-11-30'),
(18004, 001, 204, '2018-03-05', '2018-11-27', '2018-11-30'),
(18007, 002, 409, '2018-05-05', '2018-05-05', '2018-05-12'),
(18002, 002, 203, '2018-03-05', '2018-03-14', '2018-03-21'),
(18006, 002, 409, '2018-06-05', '2018-07-04', '2018-07-07'),
(18005, 003, 409, '2018-06-05', '2018-08-05', '2018-08-12'),
(18008, 004, 409, '2018-09-05', '2018-09-05', '2018-09-12');
Just counting the number of bookings per guest_id should get your the guests who have more than one booking
select a.*
from bookings a
join (
select guest_id,room_number,count(*)
from bookings
group by guest_id,room_number
having count(*)>1
)b
on a.guest_id=b.guest_id
And a.room_ number=b.room_number