SQL query (if column contains certain value move it to another column) - sql

I'm relatively new to sql, so forgive me if my explanation isn't too clear. The column "invoice date week id" in the picture below shows in what week of a specific quarter a purchase was made. What I would like to do is this:
I would like to export all instances of W11,W12,and W13 into a new column called last3weeks. In other words, if the column contains week 11(W11), week 12(W12), and week 13(W13), then move it to a new created column called 'last3weeks'.
enter image description here

I recommend using Sql IF THEN ELSE statement.
here's an example for that,
CREATE FUNCTION IncomeLevel ( monthly_value INT )
RETURNS varchar(20)
BEGIN
DECLARE income_level varchar(20);
IF monthly_value <= 4000 THEN
SET income_level = 'Low Income';
ELSEIF monthly_value > 4000 AND monthly_value <= 7000 THEN
SET income_level = 'Avg Income';
ELSE
SET income_level = 'High Income';
END IF;
RETURN income_level;
END; //
you will just need to put on the condition you want ( W11 || W12 || W13 ) and set the value to a new column you can design by "as".

Related

Custom user autonumber

I have been searching for a solution to this autonumber problem that I am having. There seems to be no definite answer anywhere.
I have a form which has a text field.
I want this form to display the next number from a field in a table.
Example: the table contains 3 records with the values D001, D002, D003
The form is used to enter new records (new data). So next time I enter data I want D004 to automatically show up on the text field for data code in the form.
How can this be done?
You can use the BeforeInsert event of the form:
Me!AutoNumber.Value = Format(Val(Nz(Right(DMax("[AutoNumber]", "[YourTable]"), 3), 0)) + 1, "\D000")
That is 1 way to do this is create a function to handle the autonumber problem u had
create function NextAutoNumber()
returns char(4)
as
begin
declare #lastval char(4)
set #lastval = (select max(autoNumber) from table)
if #lastval is null set #lastval = 'D001'
declare #i int set #i = right(#lastval,3) + 1 return 'C' + right('00' + convert(varchar(10),#i),3)
end
like this you can just call the function anytime and insert the auto number you need for the record

How to receive only the name of a month as input parameter and not entire date in pl/sql

create or replace
PROCEDURE DISPLAY_PRESC(
P_PATIENT_ID IN NUMBER,
P_MONTH IN DATE)
IS
V_patient_name PATIENT.PATIENT_NAME%TYPE;
CURSOR PRES_CURSOR IS
SELECT PRESCRIPTION_ID, PRESCRIPTION_DATE
FROM PATIENT PAT, PRESCRIPTION PRES
WHERE PAT.PATIENT_ID = P_PATIENT_ID
AND PAT.PATIENT_ID = PRES.PATIENT_ID
AND PRES.PRESCRIPTION_DATE = P_MONTH;
BEGIN
SELECT PATIENT_NAME INTO V_PATIENT_NAME
FROM PATIENT
WHERE PATIENT_ID = P_PATIENT_ID;
DBMS_OUTPUT.PUT_LINE ('List of prescriptions for: ' || V_PATIENT_NAME|| ' during: ' ||P_MONTH);
FOR PRES_REC IN PRES_CURSOR LOOP
DBMS_OUTPUT.PUT_LINE (PRES_REC.PRESCRIPTION_ID|| ' ' || PRES_REC.PRESCRIPTION_DATE);
END LOOP;
DBMS_OUTPUT.PUT_LINE ('*** END OF REPORT ***');
END DISPLAY_PRESC;
This procedure is supposed to display all the prescriptions of a particular patient for a certain month.
input parameters
eg: Patient_ID = 10;
P_Month = 'June' & not '01-Jun-07' like I currently have to enter it.
thanks in advance for the help.
try this code to display prescriptions in certain month in all years:
create or replace PROCEDURE DISPLAY_PRESC(P_PATIENT_ID IN NUMBER,
P_MONTH IN varchar2)
IS
V_patient_name PATIENT.PATIENT_NAME%TYPE;
CURSOR PRES_CURSOR IS
SELECT PRESCRIPTION_ID, PRESCRIPTION_DATE
FROM PATIENT PAT, PRESCRIPTION PRES
WHERE PAT.PATIENT_ID = P_PATIENT_ID
AND PAT.PATIENT_ID = PRES.PATIENT_ID
------ modified
AND trim(Initcap(to_char(PRES.PRESCRIPTION_DATE, 'month')) ) = trim(Initcap(P_MONTH))
------ added
order by PRES.PRESCRIPTION_DATE ;
BEGIN
SELECT PATIENT_NAME
INTO V_PATIENT_NAME
FROM PATIENT
WHERE PATIENT_ID = P_PATIENT_ID;
DBMS_OUTPUT.PUT_LINE('List of prescriptions for: ' || V_PATIENT_NAME ||
' during: ' || Initcap(P_MONTH) );
FOR PRES_REC IN PRES_CURSOR LOOP
DBMS_OUTPUT.PUT_LINE(PRES_REC.PRESCRIPTION_ID || ' ' ||
PRES_REC.PRESCRIPTION_DATE);
END LOOP;
DBMS_OUTPUT.PUT_LINE('*** END OF REPORT ***');
END DISPLAY_PRESC;
I suggest you to keep p_month as date parameter and handle it in your program interface code before sending it as parameter for DISPLAY_PRESC procedure.
Date object is a full date which includes year,month, day, hour, minutes, seconds.
If you want to get only a month you should get either a VARCHAR2, or a number, and migrate it to the required date.
There's no "month" data type in Oracle, so if you want to handle only monthes you'll have to do it manually in your code.
The way most of the systems do the same thing is getting to full dates, which they extract data between these dates (with days, and year), and that way bypass the problem you face right now.
Also remember that each year there is June, so you would probably need the year as input - so send in 06/01/2014 00:00:00 is actually helpful a bit - since you get one object, which you can extract two pieces of data from.

Oracle UPDATE has no effect

I am working on Sql Developper an I created the following procedure in a package:
PROCEDURE VALIDER(a_session IN NUMBER) AS
i NUMBER;
TYPE type_tab IS TABLE OF PANIER%ROWTYPE;
tabSeances type_tab;
BEGIN
SELECT * BULK COLLECT INTO tabSeances
FROM PANIER
WHERE a_session = sessionweb;
i:=0;
FOR i IN 1 .. tabSeances.count LOOP
-- UPADTE DU NOMBRE DE PLACES LIBRES
BEGIN
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND day = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
--UPDATE ON PANIER
UPDATE PANIER
SET valide = 1
WHERE sessionweb = a_session
AND num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN raise_application_error(-20035, 'Pas de données');
WHEN OTHERS THEN raise_application_error(-20006,'Autres Erreurs');
END;
END LOOP;
END VALIDER;
The procedure executes normaly and I don't get an error.
I have a kind of product cart: "PANIER". I loop all the entries in thsi cart for one person (session) to validate them in the database and decrement the total number of seats.
But the field "remaining-seats" (from PROJECTIONS) in the first update don't work. The field isn't updated. I have already tried with other values but nothing.
I am sure that the procedure is executetd because the second update still works. It marks the cart entry as "CONFIRMED".
I don't have any trigger on this field.
My tables contains valid data (<>NULL).
I execute this procedure like this (in a BEGIN END; block):
CMDPLACES.VALIDER(1);
Thank for your reply.
Is it day or dateseance in your first update?
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
Also as #ThorstenKettner was mentioning, the timestamp data in the date , may fail while comparing, so we have TRUNCATE the timestamp data using TRUNC() [if needed]!
If the date column is indexed, beware the index will not be used by the database .
To handle NO Data in UPDATE, you can check (SQL%ROWCOUNT > 0) to identify the number of rows updated!
Your first update compares days. What data type are these? In case you deal with DATETIME, make sure to compare without the time part if any. Use TRUNC to achieve this.
AND TRUNC(day) = TRUNC(tabseances(i).dateseance)

PL/SQL Storing and calling procedure

I am currently working on a PL/SQL problem where I have to create a cursor inside a procedure that will give the appropriate discount for a given item (10% for prices >= $100 and 5% for prices >= $10). When I have to call the procedure, I need to display the Order Number, customer First Name, Last Name, and the Total Net Cost of the items after the discount for a specific order number (in this case I need to display for order number 2). I can't get it to display this information.
Here is my code for creating the procedure with a cursor so far.
CREATE OR REPLACE PROCEDURE ComputeOrderTotal
(no_id IN orders.o_id%TYPE,
cfirst IN customer.c_first%TYPE,
clast IN customer.c_last%TYPE,
TotalNetCost OUT orders.ordertotal%TYPE) IS
CURSOR OrderCursor IS
SELECT order_line.inv_id, inv_price, ol_quantity, inv_price*ol_quantity AS ExtPrice,
CASE
WHEN inv_price*ol_quantity >= 100 THEN 0.9*(inv_price*ol_quantity)
WHEN inv_price*ol_quantity >= 10 THEN 0.95*(inv_price*ol_quantity)
ELSE
inv_price*ol_quantity
END AS NetCost
FROM inventory, order_line, orders, customer
WHERE orders.o_id = customer.c_id;
OrderRow OrderCursor%ROWTYPE;
BEGIN
OPEN OrderCursor;
LOOP
FETCH OrderCursor INTO OrderRow;
EXIT WHEN OrderCursor%NOTFOUND;
TotalNetCost :=TotalNetCost + OrderRow.NetCost;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Order Number: ' || no_id || 'First Name: ' || cfirst || 'Last Name: ' ||
clast || 'Total Net Cost: ' || TO_CHAR(TotalNetCost, '$0999.99'));
END;
And here is my code for calling the procedure.
DECLARE
no_id orders.o_id%TYPE;
cfirst customer.c_first%TYPE;
clast customer.c_last%TYPE;
TotalNetCost orders.ordertotal%TYPE;
BEGIN
ComputeOrderTotal(2, cfirst, clast, TotalNetCost);
END;
Thanks for the help!
i am not sure but your conditions could be the problem as your second condition contradicts the first. for example 110 satisfy the first condition but it also satisfy the second condition.
WHEN inv_price*ol_quantity >= 100 THEN 0.9*(inv_price*ol_quantity)
WHEN inv_price*ol_quantity >= 10 THEN 0.95*(inv_price*ol_quantity)
i would suggest changing second condition to <100 and >=10
Add this line to the top of the code calling the procedure.
Alter session set serveroutput on;

Visual Fox Pro 6.0 Query of Logical DataType not working!

My current system has a query to generate a tax report. The problem is that sometimes orders go into our system that never get submitted but are still counted in the tax report. The flag that sets an order as submitted is called 'complete' and it will be set to TRUE using the logical datatype.
Two issues arise from the following code. First, it seems as though the field I am using as a constraint 'complete' is a FoxPro reserved function because it lights up in blue while in FoxPro. The second problem is that it will not exclude those records that never get submitted (basically the constraint is not working).
EDITED CODE:
sele bkmast
set order to county
set filt to between(sysdate, m.ld_start, m.ld_end)
go top
m.lh_countylines = ''
select 000000.0000 as ordamt, import, county, 00000000.00 as amount, date() as start, date() as end dist;
from bkmast ;
where !empty(county) ;
.and. alltrim(county) !='0' ;
.and. alltrim(county) !='8.00_Wyoming' ;
.and. alltrim(county) !='Select County' ;
order by county ;
into table countytax
m.ln_total=0
m.ln_countamt = 0
scan
m.lc_county = alltrim(county)
sele bkmast
seek m.lc_county
sum tax to m.ln_amt while county=m.lc_county
seek m.lc_county
sum ordamt to m.ln_ordamt while county=m.lc_county
sele countytax
replace ordamt with m.ln_ordamt
replace amount with m.ln_amt
replace startDate with m.ld_start
replace endDate with m.ld_end
m.ln_countamt = m.ln_countamt + ordamt
m.ln_total = m.ln_total + amount
m.lh_countylines = m.lh_countylines+elemerge(html_frm("TAXCOUNTY1"))
endscan
Any help is greatly appreciated.
Having worked with Foxpro since FoxBase back in '87, I've never known a "complete" command, nor is it directly documented in the VFP Help (yet as stated, DOES highlight in blue as a function call via Complete() ). Additionally the .AND. is long ago old indicator of query. The "End" though IS a keyword. I would try by qualifying the columns by adding the alias to the query and changing End to EndDate (and pairing up Start to StartDate), such as...
From the result of your other comment, I would do your pre-querying directly in the select statement, then do your updates...
SELECT
bk.Import,;
bk.county,;
sum( bk.OrdAmt ) AS OrdAmt,;
sum( bk.Tax ) AS Amount,;
m.ld_Start AS startDate,;
m.ld_End AS endDate;
FROM ;
bkmast bk ;
where ;
sysdate between m.ld_start and m.ld_End;
AND NOT empty( ALLTRIM( bk.county )) ;
AND NOT alltrim( bk.county ) == '0' ;
and NOT alltrim( bk.county ) == '8.00_Wyoming' ;
and NOT alltrim( bk.county ) == 'Select County' ;
AND bk.complete;
group by ;
bk.Import,;
bk.county;
order by;
bk.county ;
into;
table countytax
In this case, since the aggregations of order amount and tax, you don't need to go back to the BKMast table... its already done... you can just cycle through the result set directly. The only thing left would be to sum up the total tax and order amounts... If those variables are not used within your elemerge(html_frm("TAXCOUNTY1")) call, you can just pre-sum those directly
select CountyTax
sum OrdAmt, Amount to m.ln_CountAmt, m.ln_Total
scan
*/ These two already summed up from before the scan loop
** m.ln_countamt = m.ln_countamt + ordamt
** m.ln_total = m.ln_total + amount
*/ Now, continue with the eleMerge() function which will already have the
*/ values in the CountyTax table already summed up
m.lc_county = alltrim(county)
m.lh_countylines = m.lh_countylines+elemerge(html_frm("TAXCOUNTY1"))
endscan
What happens if you run a query where the only this in the WHERE clause is complete:
SELECT ;
000000.0000 OrdAmt,;
bk.Import,;
bk.county,;
00000000.00 Amount,;
date() as startDate,;
date() as endDate;
from bkmast bk;
where bk.Complete ;
into cursor csrTest
Does that get the right set of records? What I'm getting at is that maybe the Complete field doesn't contain what you think it does.
Tamar