DELIMITER //
CREATE PROCEDURE valor()
BEGIN
IF (select Garantia from repuestos_repuesto where Garantia = 'N' limit 1) = 'N' then
Select re.id ,ve.marca, ve.modelo, ve.año, re.Nombre_repuesto
from vehiculos_vehiculo as ve inner join repuestos_repuesto as re on re.Vehiculo_id = ve.id
where ve.marca='Chevrolet' and ve.modelo='Aveo Family' and ve.año = '2015' and re.Nombre_repuesto = 'Guardachoque' and re.Garantia = 'N'
Order By re.Precio Limit 1;
else
Select re.id ,ve.marca, ve.modelo, ve.año, re.Nombre_repuesto
from vehiculos_vehiculo as ve inner join repuestos_repuesto as re on re.Vehiculo_id = ve.id
where ve.marca='Chevrolet' and ve.modelo='Aveo Family' and ve.año = '2015' and re.Nombre_repuesto = 'Guardachoque' and re.Garantia = 'S'
Order By re.Precio Limit 1;
END IF;
END //
DELIMITER ;
call valor()
The idea is that in the first if it returns me the vehicles that do not have a guarantee and shows me the lowest price, and in the else those that do have a guarantee, but it does not show me any data when it goes to the else.
This spare part should print the stored procedure, in the else but it doesn't.
I have a stored procedure with 1 parameter but linked to 3 tables, I want to display all of the table with one parameter with this query
CREATE DEFINER=`brambang`#`%` PROCEDURE `Read_discount_campaign`(IN Insert_ID INT(10)
)
proc:
BEGIN
DECLARE is_insert_id INT(10);
DECLARE param_1_message TEXT;
SET #is_insert_id = Insert_ID;
SELECT CONVERT( CONCAT('Maaf, ID discount_campaign tidak bisa \'0\'') USING UTF8) INTO param_1_message;
IF (Insert_ID = 0) THEN
SELECT param_1_message AS message;
LEAVE proc;
END IF;
IF (Insert_ID != 0) THEN
SELECT * FROM discount_campaigns where
id = #is_insert_id;
END IF;
IF (Insert_ID != 0) THEN
SELECT * FROM discount_campaign_advanced where
discount_campaign_id = #is_insert_id;
END IF;
IF (Insert_ID != 0) THEN
SELECT dcp.discount_campaign_id, CASE WHEN dcp.active = 0
THEN dcp.product_id ELSE pc.category_id END as discount_campaign_product
FROM discount_campaign_product dcp JOIN product_categories pc
ON dcp.product_id = pc.product_id
WHERE dcp.discount_campaign_id = Insert_ID;
END IF;
END
After I run this, the output was only from this query (last IF logic)
IF (Insert_ID != 0) THEN
SELECT dcp.discount_campaign_id, CASE WHEN dcp.active = 0
THEN dcp.product_id ELSE pc.category_id END as discount_campaign_product
FROM discount_campaign_product dcp JOIN product_categories pc
ON dcp.product_id = pc.product_id
WHERE dcp.discount_campaign_id = Insert_ID;
END IF;
Instead what I want is it displays all of the logic not only the last one, how to combine all of this logic so the output was from all of the logic, not only from the last logic, is it use cross join?
I'm in a problem with the following query ..
After inserting in the table rtoxvta record by record, I need before the end of the loop eliminate the record of the vta table prevously selected.
For that i declare a new variable and assign it the vta id .. but where do I do it?
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
CREATE PROCEDURE ROWPERROW()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE indexx INT DEFAULT 0;
#DECLARE aux INT DEFAULT 0;
SELECT COUNT(*) FROM rto INTO n;
SET n = n +1;
SET indexx=0;
WHILE indexx<n DO
INSERT INTO rtoxvta (fecharto, importerto, fechavta, importevta)
SELECT r.fecha, r.importe, v.fecha, v.importe
FROM vta v
left outer join rto r
ON r.id = indexx
WHERE v.fecha >= r.fecha
AND (
(v.importe = r.importe) OR
(v.importe + 2 = r.importe) OR
(v.importe + 1 = r.importe) OR
(v.importe - 1 = r.importe) OR
(v.importe - 2 = r.importe))
LIMIT 1;
SET indexx = indexx + 1;
#DELETE FROM vta WHERE id = aux;
END WHILE;
End;
;;
CALL ROWPERROW();
You'll have to do it as two steps. First get the ID of the record you're going to insert into a variable, then insert that record. Then you can delete the record.
WHILE indexx<n DO
SELECT v.id, r.id INTO #v_id, #r_id
FROM vta v
join rto r
ON r.id = indexx
WHERE v.fecha >= r.fecha
AND r.importe BETWEEN v.importe - 2 AND v.importe + 2
LIMIT 1;
INSERT INTO rtoxvta (fecharto, importerto, fechavta, importevta)
SELECT r.fecha, r.importe, v.fecha, v.importe
FROM vta v
CROSS JOIN rto r
WHERE v.id = #v_id AND r.id = #r_id;
SET indexx = indexx + 1;
DELETE FROM vta WHERE id = #v_id;
END WHILE;
Also, if you're using a column from rto in the WHERE clause, you should use INNER JOIN rather than LEFT OUTER JOIN. The WHERE condition will not match any rows that don't have a match in rto, so there's no point in using an outer join.
I have the below code.
There is one which is one part which is "ISNULL(PO101_EXT_COST, 0)*MM01.MM021_RATE AS Amount, "
I will like to change to a if else statement.
When "MM01.MM021_RATE" = '1' then PO101_EXT_COST * MM021_FOREIGN_RATE
When "MM01.MM021_RATE" is not = '1' then PO101_EXT_COST * MM021_RATE
How can i change my code below?
SELECT
CASE
When MM01.MM021_RATE = 1
Then ISNULL(PO101_EXT_COST, 0)*MM01.MM021_FOREIGN_RATE
Else ISNULL(PO101_EXT_COST, 0)*MM01.MM021_RATE
END AS Amt END AS Amount,
ISNULL(IN100_INV_CODE,'') AS [Item Code],
ISNULL(IN006_DESC,'') AS Major,
ISNULL(IN007_DESC,'') AS Minor,
ISNULL(IN100_DESC,'') AS Item,
ISNULL(PO100_PO_REQ, 0) AS [PO #],
ISNULL(PO100_EVT_ID, 0) AS [Ev ID],
ISNULL(EV200_EVT_DESC, '') AS [Ev Desc],
ISNULL(PO101_EXT_COST, 0) AS OriginalAmt,
ISNULL(PO101_PHASE, '') AS Phase,
ISNULL(PO101_STATUS, '') AS Status,
ISNULL(EV870_ACCT_SECURITY,'') AS [ARCtl],
ISNULL(PO102_ACCOUNT,'') AS [GL Account],
MM01.MM021_EFFECTIVE_DATE,
MM01.MM021_RATE,
MM01.MM021_FOREIGN_RATE,
(PO101_ORG_CODE) AS ORG,
(PO101_CURRENCY) AS Currency, (PO100_APPROVAL) AS Approval
FROM PO101_ORD_DTL
LEFT OUTER JOIN PO100_ORDERS ON
PO100_ORG_CODE = PO101_ORG_CODE AND
PO100_PO_REQ = PO101_PO_REQ
LEFT JOIN PO102_DISTR ON
PO102_ORG_CODE = PO101_ORG_CODE AND
PO102_PO_REQ = PO101_PO_REQ AND
PO102_PO_REQ_SEQ = PO101_ORD_SEQ
LEFT OUTER JOIN EV200_EVENT_MASTER ON
PO100_ORG_CODE = EV200_ORG_CODE AND
PO100_EVT_ID = EV200_EVT_ID
LEFT OUTER JOIN MM021_CURRENCY_RATES MM01 ON
PO101_CURRENCY = MM01.MM021_CODE
INNER JOIN
(SELECT MM021_CODE, MAX(MM021_EFFECTIVE_DATE) AS EFFECTIVE_DATE
FROM MM021_CURRENCY_RATES
WHERE MM021_FOREIGN_RATE > 0 AND MM021_TO_CODE = '***'
GROUP BY MM021_CODE) MM02 ON
MM01.MM021_CODE = MM02.MM021_CODE AND
MM01.MM021_EFFECTIVE_DATE = MM02.EFFECTIVE_DATE
LEFT OUTER JOIN IN100_INV_MASTER ON
PO101_ITEM = IN100_INV_CODE AND
PO101_ORG_CODE = IN100_ORG_CODE
LEFT OUTER JOIN IN007_MINOR_GROUP ON
IN100_ORG_CODE = IN007_ORG_CODE AND
IN100_MINOR = IN007_MINOR AND
IN100_MAJOR = IN007_MAJOR
LEFT JOIN IN006_MAJOR_GROUP ON
IN006_ORG_CODE = IN007_ORG_CODE AND
IN006_MAJOR = IN007_MAJOR
LEFT JOIN EV870_ACCT_MASTER ON
PO101_BILLTO=EV870_ACCT_CODE AND
PO101_ORG_CODE=EV870_ORG_CODE
WHERE
(PO101_ORG_CODE = '40' ) AND
(EV200_EVT_DESC = 'Tyrexpo India 2016') AND
(ISNULL(PO100_APPROVAL,'') IN ('A9')) AND
(ISNULL(PO101_STATUS, '') IN ('O','C','H')) AND
(ISNULL(PO101_PHASE, '') IN ('1')) AND
(PO101_TAX_RES_TYPE <> '8APGST')
Thanks!
/*
DROP TABLE A;
DROP TABLE B;
CREATE TEMPORARY TABLE A (ID INT, rateid int,cost int);
CREATE TEMPORARY TABLE B(ID INT,rate int,foreignrate int);
TRUNCATE TABLE A;
INSERT INTO A VALUES(1,1,1),(2,1,null),(3,2,3),(4,2,null),(5,0,null),(6,7,null) ,(7,1,null) ,(8,0,null) ;
TRUNCATE TABLE B;
INSERT INTO B VALUES(1,10,20),(2,30,40);
*/
#SELECT A.* FROM A;
#SELECT B.* FROM B;
SELECT A.*,
case
when B.id = 1 then
case
when A.cost is not null and B.foreignrate is not null then A.cost * B.foreignrate
else 0
end
when B.id is not null then
case
when A.cost is not null and B.rate is not null then A.ID * B.rate
else 0
end
else 0
END AS AMT
FROM A
LEFT OUTER join B on B.ID = A.rateid
So I have a routine that does (pseudo-code):
$rows = SELECT DISTINCT a, b FROM t1;
foreach($rows as $row) {
SET #i = 0;
UPDATE t1 SET c_index = #i := (#i+1)
WHERE a = $row[a] and b = $row[b] ORDER BY c DESC;
}
The point is to number a subset of rows by the way they are sorted. Works fine, but this is update runs thousands of times so is pretty slow. To speed it up I want to put it in a stored procedure.
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE vA, vB, i INT;
DECLARE cur1 CURSOR FOR
SELECT DISTINCT a, b
FROM t1 WHERE ...;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
WHILE done = 0 DO
FETCH cur1 INTO vA, vB;
IF done = 0 THEN
SET i=0;
UPDATE t1
SET c_index = i:= (i+1)
WHERE a = vA AND b = vB
ORDER BY c DESC;
END IF;
END WHILE;
CLOSE cur1;
END
However, when creating the above procedure MySQL says there is a syntax error at "i := ...". If I use a session variable for 'i' it works (#i). Using a session variable in a stored procedure is not very elegant. How can the above stored procedure be fixed without using a session variable for 'i'?
UPDATED: Since MySQL cursors are not updatable (read-only) there is no much sense of using one in your case. Almost everything you can possibly think of can be expressed just by pure UPDATE statement(s).
If (a, b, c) are unique you can do it this way
UPDATE table1 t JOIN
(
SELECT a, b, c,
(
SELECT 1 + COUNT(*)
FROM table1
WHERE a = t.a
AND b = t.b
AND c > t.c
) rnum
FROM table1 t
) s
ON t.a = s.a
AND t.b = s.b
AND t.c = s.c
SET t.c_index = s.rnum
Here is SQLFiddle demo
or if you happen to have some sort of id (e.g. auto_increment column) then
UPDATE table1 t JOIN
(
SELECT id,
(
SELECT 1 + COUNT(*)
FROM table1
WHERE a = t.a
AND b = t.b
AND c > t.c
) rnum
FROM table1 t
) s
ON t.id = s.id
SET t.c_index = s.rnum
Here is SQLFiddle demo