I have 2 tables , master and current table( refreshed very hr).
Both the table shave same structure:
Chk | description |state | date
I need to update / append ( add the new row ) into the master table if :
1) rows that have new IDs or
2) if a particular variable ( 'state' in this case) has changed. I tried to do it using below without success :
INSERT into AGILE_TICKETS_DLY
SELECT * FROM CURR_AGILE_TICKETS curr
WHERE EXISTS (SELECT * FROM AGILE_TICKETS_DLY mstr
WHERE (curr.chk != mstr.chk) OR ( curr.chk = mstr.chk and
mstr.state != curr.state))
Any pointers on how to achieve this ?
You can try this pair of queries:
-- insert new rows
insert into agile_tickets_dly
select * from curr_agile_tickets
where chk not in (select chk from agile_tickets_dly);
-- update updated rows
update agile_tickets_dly x
join
(
select b.chk chk,b.description description,b.state state,b.date date
from agile_tickets_dly a, curr_agile_tickets b
where
a.chk=b.chk and
(a.description != b.description or a.state != b.state or a.date != b.date)
) y
on x.chk=y.chk
set x.description = y.description, x.state= y.state, x.date = y.date;
Illustration:
select * from agile_tickets_dly;
+------+-------------+---------+------------+
| chk | description | state | date |
+------+-------------+---------+------------+
| 0 | desc-0 | state-1 | 01-01-2017 |
| 1 | desc-1 | state-1 | 01-01-2018 |
| 2 | desc-2 | state-2 | 01-02-2018 |
| 3 | desc-3 | state-3 | 01-03-2018 |
+------+-------------+---------+------------+
-- one new row with chk=4, three updated rows with chk=1,2,3
select * from curr_agile_tickets;
+------+----------------+-----------------+----------------+
| chk | description | state | date |
+------+----------------+-----------------+----------------+
| 0 | desc-0 | state-1 | 01-01-2017 |
| 1 | desc-1 | state-1 | date-1-updated |
| 2 | desc-2-updated | state-2 | 01-02-2018 |
| 3 | desc-3 | state-3-updated | 01-03-2018 |
| 4 | desc-4 | state-4 | 01-04-2018 |
+------+----------------+-----------------+----------------+
-- after executing the two queries
select * from agile_tickets_dly;
+------+----------------+-----------------+----------------+
| chk | description | state | date |
+------+----------------+-----------------+----------------+
| 0 | desc-0 | state-1 | 01-01-2017 |
| 1 | desc-1 | state-1 | date-1-updated |
| 2 | desc-2-updated | state-2 | 01-02-2018 |
| 3 | desc-3 | state-3-updated | 01-03-2018 |
| 4 | desc-4 | state-4 | 01-04-2018 |
+------+----------------+-----------------+----------------+
I tried to do this in 2 separate steps:
1) First I append all new rows with IDs : this worked
INSERT into AGILE_TICKETS_DLY
SELECT * FROM CURR_AGILE_TICKETS curr
WHERE not EXISTS (SELECT * FROM AGILE_TICKETS_DLY mstr
WHERE (curr.chk = mstr.chk));
But then, I tried to do below got an error
2) Then replace the 'State' variable with new value:
INSERT into AGILE_TICKETS_DLY_1 (state)
SELECT state
from CURR_AGILE_TICKETS_1 curr
where exists ( select * from AGILE_TICKETS_DLY_1 mstr where curr.chk =
mstr.chk);
But this gives me an error :
SQL Error (1364) : Field 'chk' doesn't have a default value.
What does that mean ?
Related
I have a Mysql table with the following data.
|ID | Date | BillNumber|BillMonth | Amount | Name |AccNum |
| 2 |2015-09-25| 454345 | 092015 | 135.00 |Andrew Good| 735976|
| 3 |2015-09-26| 356282 | 092015 | 142.00 |Peter Pan | 123489|
| 4 |2015-08-11| 312738 | 082015 | 162.00 |Andrew Good| 735976|
| 5 |2015-07-12| 287628 | 072015 | 220.67 |Andrew Good| 735976|
| 6 |2015-06-12| 100756 | 062015 | 556.34 |Andrew Good| 735976|
What I wanted to achieve is to retrieve the data of Andrew Good with AccNum 735976 for the BillMonth of 092015, provided that the user can entry any of his BillNumber(past/current).
If the reason that that row is of interest is because it is the latest of his rows, try:
select *
from tbl t
where name = ( select name
from tbl
where billnumber = 100756 -- can be any of his
)
and date = ( select max(date)
from tbl x
where x.name = t.name
)
(the billnumber can be any of his)
I have a two tables :
mysql> select * from quizquestionbank;
| ID | QuestionFilePath | CorrectAnswer | EndDate |
--------------------------------------------------------------
| 1 | p.wav | 1 |2014-05-12 12:00:00 |
| 2 | q.wav | 2 |2014-05-12 12:00:00 |
| 3 | a.wav | 3 |2014-05-12 12:00:00 |
| 4 | b.wav | 1 |2014-05-12 12:00:00 |
| 5 | m.wav | 3 |2014-05-12 12:00:00 |
Second table is :
mysql> select * from quizuserdetails;
| ID | MSISDN | QuestionIdDetails | AnswerRecord |
--------------------------------------------------
| 1 | 235346 | 1,3,4,5 | S,F,S,F |
| 2 | 564574 | 4,5,67,88 | F,S,F,s |
| 3 | 500574 | 5,55,66,44,2 | F,F,F,F |
I want to get the IDs from table 1 which :
1. are not there in QuestionIdDetails column of second table and
2. less than current date and time.
Following Query gives me records required for first point:
Select qb.ID,qb.EndDate
from quizquestionbank qb
left join quizuserdetails qd
on find_in_set(qb.id, QuestionIdDetails) > 0
and msisdn = '235346'
where qd.id is null
But for second requirement following query gives error :
Select *
from predictionfootball
where '2014-05-10 00:00:00' <
(Select qb.ID,qb.EndDate
from quizquestionbank qb
left join quizuserdetails qd
on find_in_set(qb.id, QuestionIdDetails) > 0
and msisdn = '235346'
where qd.id is null)
Please tell me the way to do it.
Try that:
Select qb.ID,qb.EndDate
from quizquestionbank qb
left join quizuserdetails qd
on find_in_set(qb.id, QuestionIdDetails) > 0
and msisdn = '235346'
where qd.id is null
AND qb.EndDate < '2014-05-10 00:00:00' ------> added this line
I have a table having following structure:
| pid | email | email_type |
| 1 | x | 1 |
| 1 | y | 2 |
| 1 | z | 3 |
| 2 | ab | 1 |
| 3 | cd | 2 |
Now I want my result for the pid parameter in format for email_type[1 & 2] only:
Case pid=1
| pid | email_p | email_w |
| 1 | x | y |
Case pid=2
| 2 | ab | NULL |
Case pid=3
| 3 | NULL | cd |
Here email_p represents email_type=1 & email_w represents email_type=2
I am using following query, and its working fine except for a case pid=2. Case I & Case III are successfully fetched. Please provide some solution with good explanation(if possible).
SELECT `e`.`pid`, `e`.`email` AS `email_p`, `e1`.`email` AS `email_w` FROM `table1` AS `e` LEFT JOIN `table1` AS `e1` ON e.pid=e1.pid AND e1.email_type=2 WHERE (e.pid IN (1) AND e.email_type=1)
It fails when e.pid = 2 and it returns empty result set & please provide solution e.pid IN (1,2,3) holds good for required format.#MYSQL
Try This
SELECT pid,
MAX(CASE WHEN email_type=1 THEN email END ) as email_p ,
MAX(CASE WHEN email_type=2 THEN email END ) as email_w
FROM tableName
WHERE email_type IN (1,2)
GROUP BY pid
SQL Fiddle DEMO
I have a couple of very large tables (over 400,000 rows) that look like the following:
+---------+--------+---------------+
| ID | M1 | M1_Percentile |
+---------+--------+---------------+
| 3684514 | 3.2997 | NULL |
| 3684515 | 3.0476 | NULL |
| 3684516 | 2.6499 | NULL |
| 3684517 | 0.3585 | NULL |
| 3684518 | 1.6919 | NULL |
| 3684519 | 2.8515 | NULL |
| 3684520 | 4.0728 | NULL |
| 3684521 | 4.0224 | NULL |
| 3684522 | 5.8207 | NULL |
| 3684523 | 6.8291 | NULL |
+---------+--------+---------------+...about 400,000 more
I need to assign each row in the M1_Percentile column a value that represents "the percent of rows with M1 values equal or lower to the current row's M1 value"
In other words, I need:
I implemented this sucessfully, but it is FAR FAR too slow. If anyone could create a more efficient version of the following code, I would really appreciate it!
UPDATE myTable AS X JOIN (
SELECT
s1.ID, COUNT(s2.ID)/ (SELECT COUNT(*) FROM myTable) * 100 AS percentile
FROM
myTable s1 JOIN myTable s2 on (s2.M1 <= s1.M1)
GROUP BY s1.ID
ORDER BY s1.ID) AS Z
ON (X.ID = Z.ID)
SET X.M1_Percentile = Z.percentile;
This is the (correct but slow) result from the above query if the number of rows is limited to the ones you see (10 rows):
+---------+--------+---------------+
| ID | M1 | M1_Percentile |
+---------+--------+---------------+
| 3684514 | 3.2997 | 60 |
| 3684515 | 3.0476 | 50 |
| 3684516 | 2.6499 | 30 |
| 3684517 | 0.3585 | 10 |
| 3684518 | 1.6919 | 20 |
| 3684519 | 2.8515 | 40 |
| 3684520 | 4.0728 | 80 |
| 3684521 | 4.0224 | 70 |
| 3684522 | 5.8207 | 90 |
| 3684523 | 6.8291 | 100 |
+---------+--------+---------------+
Producing the same results for the entire 400,000 rows takes magnitudes longer.
I cannot test this, but you could try something like:
update table t
set mi_percentile = (
select count(*)
from table t1
where M1 < t.M1 / (
select count(*)
from table));
UPDATE:
update test t
set m1_pc = (
(select count(*) from test t1 where t1.M1 < t.M1) * 100 /
( select count(*) from test));
This works in Oracle (the only database I have available). I do remember getting that error in MySQL. It is very annoying.
Fair warning: mysql isn't my native environment. However, after a little research, I think the following query should be workable:
UPDATE myTable AS X
JOIN (
SELECT X.ID, (
SELECT COUNT(*)
FROM myTable X1
WHERE (X.M1, X.id) >= (X1.M1, X1.id) as Rank)
FROM myTable as X
) AS RowRank
ON (X.ID = RowRank.ID)
CROSS JOIN (
SELECT COUNT(*) as TotalCount
FROM myTable
) AS TotalCount
SET X.M1_Percentile = RowRank.Rank / TotalCount.TotalCount;
I'm trying to update a date column of records satisfying following condition:
Column STATION has to be the same as STATION from record with FILTER_NR = x
AND STATUS IN (11, 12, 13)
AND FILTER_NR != x
If x = 3 the UPDATE Statement, I'm looking for, should change the Table FILTER from:
+-----------+------------+---------+---------+
| FILTER_NR | PROBEDATE | STATION | STATUS |
+-----------+------------+---------+---------+
| 1 | 2011-06-01 | 1 | 10 |
| 2 | 2011-06-02 | 1 | 11 |
| 3 | 2011-06-03 | 1 | 12 |
| 4 | 2011-06-04 | 2 | 13 |
+-----------+------------+---------+---------+
to:
+-----------+------------+---------+----------+
| FILTER_NR | PROBEDATE | STATION | STATUS |
+-----------+------------+---------+----------+
| 1 | 2011-06-01 | 1 | 10 | -> not changed
| 2 | 2011-06-01 | 1 | 11 | -> changed
| 3 | 2011-06-03 | 1 | 12 | -> not changed
| 4 | 2011-06-04 | 2 | 13 | -> not changed
+-----------+------------+---------+----------+
I began with following SQL Statement, do you know how I can complete it?
UPDATE FILTER SET PROBEDATE = ADDDATE(PROBEDATE, -1)
WHERE FILTER_NR IN (...);
This should work for you:
UPDATE `FILTER` `F`
INNER JOIN `FILTER` `F1` ON `F1`.`FILTER_NR` = 3 AND `F1`.`STATION` = `F`.`STATION`
SET `F`.`PROBEDATE` = CURDATE()
WHERE `F`.`FILTER_NR` != 3
AND `F`.`STATUS` IN (11, 12, 13);
In my example, I've set PROBEDATE to the current date but please feel free to set it to what you might like.
Hope this helps!
You could ty something like this:
UPDATE FILTER
SET PROBEDATE = PROBEDATE - inteval 1 day
WHERE STATUS IN (11,12,13)
AND FILTER_NR != 3
AND STATION IN
(
SELECT STATION
FROM (
SELECT *
FROM FILTER
) as SubQueryAlias
WHERE FILTER_NR = 3
)