Update Table with Case stmt - mysql

This is a fun side project I have been working on. I added a column for weight (op1w to op12w) to go with the description (op_1 to op_12). Now I need to go back through and update all entries with the appropriate op1w to op12w depending on the op_1 to op_12. Here is a part of the drop_log table with those columns.
Here are the values to match and what to update the op1w to op12w with (this exists as a table called mechs in the db):
mech weight
AS7 100
AWS 80
BJ 45
BLR 85
CDA 40
CN9 50
COM 25
CPL 65
CTF 70
DISC 0
DRG 60
GRF 55
HBK 50
HGN 90
JM6 65
JR7 35
KTO 55
LCT 20
ON1 75
QKD 60
RVN 35
SDR 30
SHD 55
STK 85
TBT 50
TDR 65
VTR 80
WVR 55
Would you guys help me with the case statement for this? I believe it should start something like this:
UPDATE drop_log
SET
op1w =(case when some_case_condition then something else op1w end),
op2w =(case when some_case_condition then something else op2w end)
.
Thanks for your help.
edit: OK after reading the comments, here is my attept
UPDATE drop_log
SET op1w=
CASE
WHEN op_1 = 'AS7'
THEN op1w = 100
WHEN op_1 = 'AWS'
THEN op1w = 80
.
.
.
ELSE op_1
END
CASE
WHEN op_12 = etc
THEN op12w = etc
.
.
.
ELSE op_12
END
Ok now I see what you guys are saying.. No I don't want you to fill it our for me. This is going to go on and on for each column 1-12 and then each column gets its own case for each weight possibility. Is that all there is to it? I thought it would be more involved.

The general format of your query should be:
UPDATE drop_log
SET op1w = CASE
WHEN op_1 = 'AWS' THEN '1'
WHEN op_2 = 'ABC' THEN op1
ELSE '0'
END,
op2w = CASE
WHEN op_1 = 'HDP' THEN op_1
ELSE '0'
END

Related

Why do my values show as NULL when pivoting table in MySQL

I'm using MySQL - Rows to Columns and this tutorial http://stratosprovatopoulos.com/web-development/mysql/pivot-a-table-in-mysql/#comment-6128 to help me pivot a table and it's working pretty well. Starting with this:
mediaID q_short_name start_time stop_time audio_link
ee CVV Number 208 210 j.mp3
ee Expiration Date 308 310 j.mp3
ff CVV Number 124 127 k.mp3
ff Expiration Date 166 169 k.mp3
The goal is this:
mediaID CVVNumStartT CVVNumStopT ExpDateStart_time ExpDateStop_time Aud
ee 208 210 308 310 k.mp3
ff 124 127 166 169 j.mp3
I got part of the way there with this code:
CREATE VIEW test__extension AS (
SELECT amr_text.*,
CASE WHEN q_short_name = 'CVV Number' THEN amr_text.start_time END AS
CVV_Start_Time,
CASE WHEN q_short_name = 'CVV Number' THEN amr_text.stop_time END AS
CVV_Stop_Time,
CASE WHEN q_short_name = 'Expiration Date' THEN amr_text.start_time END
AS Expiration_Start_Time,
CASE WHEN q_short_name = 'Expiration Date' THEN amr_text.stop_time END
AS Expiration_Stop_Time, FROM amr_text);
CREATE VIEW test_extension_pivot AS (SELECT mediaID,
SUM(CVV_Start_Time) AS CVV_Start_Time,
SUM(CVV_Stop_Time) AS CVV_Stop_Time,
SUM(Expiration_Start_Time) AS Expiration_Start_Time,
SUM(Expiration_Stop_Time) AS Expiration_Stop_Time,
FROM test_extension GROUP BY mediaID);
This creates columns exactly like the goal table. But now the values for everything except the mediaIDs are rendered as NULL. My questions are, why did they get replaced by NULL, and what can I use instead of SUM to render the values of Expiration and CVV Start and Stop Time as they are in the original table?

SQL - Calculate two fields in one Case

I have a sql query that calculates a field as follows:
Select
Case When b.xField > 10
then 20
when b.xField > 48
then 10
else 0
end as field1
from (Select CASE WHEN numberChosen < 15
THEN 10
WHEN numberChosen > 15
THEN 48
END as xField
From secondTable) B
What I need is, when field1 is 10, then do some other calculations to save on another field.
Example something like:
then 20 AND field2 = yData - 26
so when the case is on 20, then have another field equal to yData - 26.
Can that be achieved using Cases in Sql ? Have two fields calculated in a single case?
I want to calculate two fields in one Case
You Can't Do That™.
You can put two case clauses in your query like this:
Select
Case When xField > 10
then 20
when xField > 48
then 10
else 0
end as field1,
Case When xField > 10
then ydata - 26
else 0
end as field2
from myData
Or you can generate the extra field value in a wrapper query if it is really hard to compute field2
SELECT field1, CASE WHEN field1 > 10 THEN ydata -20 ELSE 0 END field2
FROM (
Select
ydata,
Case When xField > 10
then 20
when xField > 48
then 10
else 0
end as field1
from myData
) subquery
You can use the base logic that is deciding when field1 = 10 (ie. xField > 48) in the second case:
SELECT CASE WHEN xField > 48
THEN 10
WHEN xField > 10
THEN 20
ELSE 0
END as field1,
CASE WHEN xField > 48
THEN yData - 26
END as field2
FROM (SELECT CASE WHEN numberChosen < 15
THEN 10
WHEN numberChosen > 15
THEN 48
END as xField,
yData
FROM secondTable) B
I changed the order of your case because putting the > 10 condition before the > 48 condition will never let the > 48 be hit.

Same stored procedure, same tables, different DB gives different result

I have stored procedure which gives me expected result when I run it on MySQL 5. But when I tried to run same procedure on MariaDB 10.1.22, it gives me a different result.
Here is my stored procedure -
DELIMITER ;;
CREATE DEFINER=`mconnect_admin`#`%` PROCEDURE `TestCumulative`(IN
start_date TIMESTAMP,IN end_date TIMESTAMP,IN duration TEXT,IN
mno_id TEXT,IN profile_type TEXT,IN timezone TEXT)
BEGIN
SET #provisioned = 0;
SET #downloaded = 0;
SET #excludeProfileFilter = FALSE;
SET #hourlyReport = FALSE;
SET #monthlyReport = FALSE;
SET #sdate = start_date;
DROP TABLE IF EXISTS tempDates;
CREATE TEMPORARY TABLE IF NOT EXISTS tempDates(timeRange
VARCHAR(50));
DELETE FROM tempDates;
IF(profile_type = '')
THEN
SET profile_type = null;
SET #excludeProfileFilter = TRUE;
END IF;
IF (duration = 'lastDay')
THEN
SET #hourlyReport=true;
END IF;
IF (duration = 'lastYear')
THEN
SET #monthlyReport = TRUE;
END IF;
WHILE #sdate <= end_date DO
IF (#hourlyReport = TRUE)
THEN
INSERT INTO tempDates (timeRange) VALUES (HOUR(#sdate) + 1);
SET #sdate = date_add(#sdate, INTERVAL 1 HOUR);
ELSE IF(#monthlyReport = TRUE)
THEN
INSERT INTO tempDates (timeRange) VALUES (MONTH(#sdate));
SET #sdate = date_add(#sdate, INTERVAL 1 MONTH);
ELSE
INSERT INTO tempDates (timeRange) VALUES (DATE(#sdate));
SET #sdate = date_add(#sdate, INTERVAL 1 DAY);
END IF;
END IF;
END WHILE ;
SELECT CASE WHEN r.DateRange IS NULL THEN (#provisioned :=
#provisioned) ELSE (#provisioned := #provisioned + r.Provisioned)
END AS Provisioned,
CASE WHEN r.DateRange IS NULL THEN (#downloaded := #downloaded) ELSE
(#downloaded := #downloaded + r.Downloaded) END AS Downloaded,
CASE WHEN r.DateRange IS NULL THEN d.timeRange ELSE r.DateRange END
AS DateRange FROM (
SELECT sum(result.Provisioned) as Provisioned,
sum(result.Downloaded) AS Downloaded, result.DateRange FROM (
SELECT
1 As Provisioned,
0 AS Downloaded,
CASE WHEN #hourlyReport=TRUE
THEN HOUR(CONVERT_TZ(s.provisioning_date,"+00:00",timezone))
WHEN #monthlyReport=TRUE
THEN MONTH(CONVERT_TZ(s.provisioning_date,"+00:00",timezone))
ELSE DATE(CONVERT_TZ(s.provisioning_date,"+00:00",timezone))
END
AS DateRange
FROM subscription s
INNER JOIN profile_type p ON p.id = s.profile_type
WHERE s.mno_id = mno_id
AND (#excludeProfileFilter=true or p.display_name=profile_type OR p.subscription_type=profile_type)
AND DATE(CONVERT_TZ(s.provisioning_date,"+00:00",timezone)) BETWEEN DATE(CONVERT_TZ(start_date,"+00:00",timezone)) AND DATE(CONVERT_TZ(end_date,"+00:00",timezone))
UNION ALL
SELECT
0 As Provisioned,
1 As Downloaded,
CASE WHEN #hourlyReport=TRUE
THEN COALESCE(HOUR(CONVERT_TZ(r.end_download_date,"+00:00",timezone)),HOUR(CONVERT_TZ(r.last_update,"+00:00",timezone)))
WHEN #monthlyReport=TRUE
THEN COALESCE(MONTH(CONVERT_TZ(r.end_download_date,"+00:00",timezone)),MONTH(CONVERT_TZ(r.last_update,"+00:00",timezone)))
ELSE COALESCE(DATE(CONVERT_TZ(r.end_download_date,"+00:00",timezone)),DATE(CONVERT_TZ(r.last_update,"+00:00",timezone)))
END
AS DateRange
FROM subscription s
INNER JOIN profile_type p ON p.id = s.profile_type
LEFT JOIN rsp_session r ON r.profile_iccid = s.iccid
WHERE s.mno_id = mno_id
AND (#excludeProfileFilter=TRUE OR p.display_name=profile_type OR p.subscription_type=profile_type)
AND COALESCE(DATE(CONVERT_TZ(r.end_download_date,"+00:00",timezone)),DATE(CONVERT_TZ(r.last_update,"+00:00",timezone))) BETWEEN DATE(CONVERT_TZ(start_date,"+00:00",timezone)) AND DATE(CONVERT_TZ(end_date,"+00:00",timezone)) AND s.status IN('INSTALLED','ENABLED','DELETED')
) result GROUP BY result.DateRange
) r RIGHT OUTER JOIN tempDates d ON r.DateRange = d.timeRange;
END;;
DELIMITER ;
The result I am getting in MaroiaDB 10.1.22, which is not the correct one is -
2 0 2017-11-02
5 10 2017-11-03
32 16 2017-11-06
51 34 2017-11-07
64 42 2017-11-08
79 47 2017-11-09
79 48 2017-11-10
102 61 2017-11-13
116 61 2017-11-14
128 68 2017-11-15
145 71 2017-11-16
157 82 2017-11-17
196 95 2017-11-20
254 111 2017-11-21
273 118 2017-11-22
313 134 2017-11-23
323 144 2017-11-24
363 149 2017-11-27
368 152 2017-11-28
371 152 2017-11-29
403 160 2017-11-30
403 160 2017-11-01
403 160 2017-11-04
403 160 2017-11-05
403 160 2017-11-11
403 160 2017-11-12
403 160 2017-11-18
403 160 2017-11-19
403 160 2017-11-25
403 160 2017-11-26
It should be in order.
Can anyone tell what is the wrong? Or its DB issue?
Thanks in advance.
You have no order by in any of your queries. The result set can be in any order, because result sets without an order by (like tables) are unordered sets.
Hence, the database is correct. Your understanding is missing this important fact about SQL.
Add the order by that you want and the result set will be appropriately ordered in any version of the database that you use.

how to create an sql view based on calculated vales?

Hie lets assume we have the following table
TABLE NAME : DRINGE
__________________________________________________
ID PRODUCT MACHINE MASS STATE
01 1.76ann HRB 50 inlet
02 1.76ann HRB 38 inlet
03 2.55ann GUDO 45 outlet
04 95mm x 4 GUDO 36 dispatched
___________________________________________________
And the following formula:
(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
And the values to be substituted are:
INLET = 50 , 38
OUTLET=45
DISPATCHED = 36
So substituting in the above formula
[(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
We get this
(50+38 – 45 ) + 45 – 36 = 52
What I want is for the result ie 52 to be displayed in an sql view like the following view
Dringe VIEW
_____________
Total_summary|
_____________|
52 |
_____________|
.
Does anyone have any idea of an sql query I can use to do this ?
I rily need your help am stuck again, thanx in advance.
The below will follow your formula
CREATE VIEW DRINGEView AS
SELECT sum(case when state = 'inlet' then mass else 0 end) -
sum(case when state = 'outlet' then mass else 0 end)+
sum(case when state = 'outlet' then mass else 0 end) -
sum(case when state = 'dispatched' then mass else 0 end) AS Total_summary
FROM dringe
But adding outlet then subtracting outlet would be redundant. The brackets in your formula would also be redundant as all of your operators are addition/subtraction, could one of your operators be multiplication/division?
you can just add those calculations to your query in something like
(40+50+fieldName*anotherFieldName) AS calculation
and you can even use sub tables like
(40+50+(SELECT fieldName FROM anotherTable WHERE someValue) AS calculation
create view dringe_view as
select (sum(inlet) – sum(outlet) ) +sum(outlet) – sum(dispatched ) as total_summary
from tab
But your claculation can be further simplified (remove outlet - outlet) to (inlet – dispatched)

mysql,select query ,and or clause problem

i have a table named item with four attribute name,code,class,value
now i want to group them in following way:
group a: name='A',code=11,class='high',value between( (5300 and 5310),(7100 and 7200),(8210 and 8290))
group b: name='b',code=11,class='high',value between( (1300 and 1310),(2100 and 2200),(3210 and 3290))
how can i do it?
You might want to try something like this:
SELECT
CASE
WHEN code = 11 AND
class = 'high' AND
(code BETWEEN 5300 AND 5310 OR
code BETWEEN 7100 AND 7200 OR
code BETWEEN 8210 AND 8290)
THEN 'A'
WHEN code = 11 AND
class = 'high' AND
(code BETWEEN 1300 AND 1310 OR
code BETWEEN 2100 AND 2200 OR
code BETWEEN 3210 AND 3290)
THEN 'B'
ELSE Unknown
END AS name,
*
FROM your_table
ORDER BY name
You might wish to change ORDER BY to GROUP BY and you should be aware that BETWEEN includes both endpoints.
First group
select * from item
where name LIKE 'A'
and code LIKE '11'
and class LIKE 'high'
and (value BETWEEN 5300 AND 5310 OR value BETWEEN 7100 AND 7200 OR value BETWEEN 8210 AND 8290)
the same idea for group b