Select and Update in same time and gets displayed - mysql

I have this query:
SELECT MIN(id),CustomerName, Scenario,StepNo,InTransit,IsAlef,runNo,ResponseLength
FROM `RequestInfo`
WHERE `CustomerName` = 'Hotstar'
AND `ResponseContentType` like '%video/MP2T%'
AND `RequestHttpRequest` like '%segment%' ;
which gives me output like this:-
+---------+--------------+----------+--------+-----------+--------+-------+----------------+----------+
| MIN(id) | CustomerName | Scenario | StepNo | InTransit | IsAlef | runNo | ResponseLength | IsActive |
+---------+--------------+----------+--------+-----------+--------+-------+----------------+----------+
| 139 | HotStar | SearchTv | 1 | No | No | 1 | 410098 | NULL |
+---------+--------------+----------+--------+-----------+--------+-------+----------------+----------+
I want to insert string "Yes" in the last column i.e "IsActive" when the above data is being displayed but only when the IsActive is set as NULL.

Use below query
Update RequestInfo R inner join (SELECT MIN(id) as id,CustomerName, Scenario,StepNo,InTransit,IsAlef,runNo,ResponseLength
FROM `RequestInfo`
WHERE `CustomerName` = 'Hotstar'
AND `ResponseContentType` like '%video/MP2T%'
AND `RequestHttpRequest` like '%segment%')as T on R.id = T.id set R.isAcitve ='Yes' Where R.id = T.id;

Related

Sql group by date issue

I have two tables as below,
------------------ --------------------
| leads | | leads_tracking |
------------------ --------------------
| id | | tracking_id |
| lead_id | | lead_id |
| tix | | field_name |
| order_number | | date |
------------------ ---------------------
I need to get the sum of tix and group them by date (and order number is not empty)
I tried write sql:
SELECT DATE_FORMAT(tracking_leads.date, "%m.%d.%Y") as trackDate, SUM(l.tix) as sumValue
FROM leads as l
INNER JOIN tracking_leads ON l.lead_id=tracking_leads.lead_id
WHERE tracking_leads.field_name='tix'
AND l.is_active = 1
AND l.is_archive = 0
AND l.dont_show_in_list=0
AND order_number <> ''
and transaktions_nr IS NOT NULL
GROUP BY DATE_FORMAT(tracking_leads.date, "%m.%d.%Y")
I don't have all groups that I need.
What's wrong with my code please?
Add order_number to your query and check the result. You might get some idea. Try this:
SELECT order_number,DATE_FORMAT(tracking_leads.date, "%m.%d.%Y") as trackDate, SUM(l.tix) as
sumValue
FROM leads as l
INNER JOIN tracking_leads ON l.lead_id=tracking_leads.lead_id
WHERE tracking_leads.field_name='tix'
AND l.is_active = 1
AND l.is_archive = 0
AND l.dont_show_in_list=0
AND order_number <> ''
and transaktions_nr IS NOT NULL
GROUP BY order_number,tracking_leads.date

Update a column with a calculated value

Here is the table I use:
+-------------+----------+---------------------+
| sourceindex | source | pa |
+-------------+----------+---------------------+
| 0 | this | 0.13842974556609988 |
| 1 | is | 0.26446279883384705 |
| 2 | a | 0.26446279883384705 |
| 3 | book | 0.13842974556609988 |
| 4 | , | 0.26446279883384705 |
| 5 | that | 0.13842974556609988 |
I want to add a column which will be the result log(sum(pa))/pa.
Any suggestions on how I could do that?
You can use a cross join to to calculate log(sum(pa)) and in your outer you can divide the result with each value of pa colum
update
test t
join (select
`sourceindex`, `source`, `pa` , log_sum/pa new_col
from
test
cross join (select log(sum(pa)) log_sum
from test ) a
) t1
on (t.sourceindex= t1.sourceindex
and t.source = t1.source
and t.pa = t1.pa
)
set t.new_col = t1.new_col
Demo
But its better if you switch your logic to show your calculation with select query
select `sourceindex`, `source`, `pa` , log_sum/pa new_col
from
test
cross join (select log(sum(pa)) log_sum
from test ) t
Demo

MySQL Duplicate rows - specify columns

How can I run a query that finds duplicates between rows? It needs to not match one field but multiple.
Here is the EXPLAIN of the table.
+-------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| token | varchar(64) | NO | MUL | NULL | |
| maxvar | float | NO | | NULL | |
| maxvbr | float | NO | | NULL | |
| minvcr | float | NO | | NULL | |
| minvdr | float | NO | | NULL | |
| atype | int(11) | NO | | NULL | |
| avalue | varchar(255) | NO | | NULL | |
| createddate | timestamp | NO | | CURRENT_TIMESTAMP | |
| timesrun | int(11) | NO | | NULL | |
+-------------+--------------+------+-----+-------------------+----------------+
I need to match all rows that match: token,maxvar,maxvbr,minvcr,minvdr,type and avalue. If all of those fields match those in another row then treat it as a "duplicate".
Ultimately I want to run this as a delete command but I can easily alter the select.
UPDATE Still looking for solution that deletes with single query in MySQL
Just join the table to itself and compare the rows. You can make sure you keep the duplicate with the lowest ID by requiring the id to be deleted to be greater than the id of a duplicate:
DELETE FROM my_table WHERE id IN (
SELECT DISTINCT t1.id
FROM my_table t1
JOIN my_table t2
WHERE t1.id > t2.id
AND t1.token = t2.token AND t1.maxvar = t2.maxvar
AND t1.maxvbr = t2.maxvbr AND t1.minvcr = t2.minvcr
AND t1.minvdr = t2.minvdr AND t1.type = t2.type)
This query will find all duplicate records which should be deleted -
SELECT t1.id FROM table_duplicates t1
INNER JOIN (
SELECT MIN(id) id, token, maxvar, maxvbr, minvcr, minvdr, atype, avalue FROM table_duplicates
GROUP BY token, maxvar, maxvbr, minvcr, minvdr, atype, avalue
HAVING COUNT(*) > 1
) t2
ON t1.id <> t2.id AND t1.token = t2.token AND t1.maxvar=t2.maxvar AND t1.maxvbr = t2.maxvbr AND t1.minvcr = t2.minvcr AND t1.minvdr = t2.minvdr AND t1.atype = t2.atype AND t1.avalue = t2.avalue;
This query will remove all duplicates -
DELETE t1 FROM table_duplicates t1
INNER JOIN (
SELECT MIN(id) id, token, maxvar, maxvbr, minvcr, minvdr, atype, avalue FROM table_duplicates
GROUP BY token, maxvar, maxvbr, minvcr, minvdr, atype, avalue
HAVING COUNT(*) > 1
) t2
ON t1.id <> t2.id AND t1.token = t2.token AND t1.maxvar=t2.maxvar AND t1.maxvbr = t2.maxvbr AND t1.minvcr = t2.minvcr AND t1.minvdr = t2.minvdr AND t1.atype = t2.atype AND t1.avalue = t2.avalue;
SELECT token,maxvar,maxvbr,minvcr,minvdr,type, avalue,
Count(*)
FROM yourtable
GROUP BY token,maxvar,maxvbr,minvcr,minvdr,type, avalue
HAVING Count(*) > 1
This query returns all the rows that are in the table two times or more often (and how often they are).
Try:
SELECT token,maxvar,maxvbr,minvcr,minvdr,type,avalue, COUNT(*)
FROM table
GROUP BY token,maxvar,maxvbr,minvcr,minvdr,type,avalue
HAVING COUNT(*)>1

SQL Group by combination?

I am having problems selecting items from a table where a device_id can be either in the from_device_id column or the to_device_id column. I am trying to return all chats where the given device is ID is in the from_device_id or to_device_id columns, but only return the latest message.
select chat.*, (select screen_name from usr where chat.from_device_id=usr.device_id limit 1) as from_screen_name, (select screen_name from usr where chat.to_device_id=usr.device_id limit 1) as to_screen_name from chat where to_device_id="ffffffff-af28-3427-a2bc-83865900edbe" or from_device_id="ffffffff-af28-3427-a2bc-83865900edbe" group by from_device_id, to_device_id;
+----+--------------------------------------+--------------------------------------+---------+---------------------+------------------+----------------+
| id | from_device_id | to_device_id | message | date | from_screen_name | to_screen_name |
+----+--------------------------------------+--------------------------------------+---------+---------------------+------------------+----------------+
| 20 | ffffffff-af28-3427-a2bc-83860033c587 | ffffffff-af28-3427-a2bc-83865900edbe | ee | 2011-02-28 12:36:38 | kevin | handset |
| 1 | ffffffff-af28-3427-a2bc-83865900edbe | ffffffff-af28-3427-a2bc-83860033c587 | yyy | 2011-02-27 17:43:17 | handset | kevin |
+----+--------------------------------------+--------------------------------------+---------+---------------------+------------------+----------------+
2 rows in set (0.00 sec)
As expected, two rows are returned. How can I modify this query to only return one row?
mysql> describe chat;
+----------------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| from_device_id | varchar(128) | NO | | NULL | |
| to_device_id | varchar(128) | NO | | NULL | |
| message | varchar(2048) | NO | | NULL | |
| date | timestamp | YES | | CURRENT_TIMESTAMP | |
+----------------+---------------+------+-----+-------------------+----------------+
5 rows in set (0.00 sec)
select chat.*,
(select screen_name
from usr
where chat.from_device_id=usr.device_id
limit 1
) as from_screen_name,
(select screen_name
from usr
where chat.to_device_id=usr.device_id
limit 1
) as to_screen_name
from chat
where to_device_id="ffffffff-af28-3427-a2bc-83865900edbe" or
from_device_id="ffffffff-af28-3427-a2bc-83865900edbe"
group by from_device_id, to_device_id
order by date DESC
limit 1;
You need to tell SQL that it should sort the returned data by date to get the most recent chat. Then you just limit the returned rows to 1.
You shouldn't need to use a Group By at all. Rather, you can simply use the Limit predicate to return the last row. In addition, you shouldn't need subqueries as you can use simply Joins. If chat.from_device_id and chat.to_device_id are both not-nullable, then you can replace the Left Joins with Inner Joins.
Select chat.id
, chat.from_device_id
, chat.to_device_id
, chat.message
, chat.date
, FromUser.screen_name As from_screen_nam
, ToUser.screen_name As to_screen_name
From chat
Left Join usr As FromUser
On FromUser.device_id = chat.from_device_id
Left Join usr As ToUser
On ToUser.device_id = chat.to_device_id
Where chat.to_device_id="ffffffff-af28-3427-a2bc-83865900edbe"
Or chat.from_device_id="ffffffff-af28-3427-a2bc-83865900edbe"
Order By chat.date Desc
Limit 1

Joining two tables without returning unwanted row

My table structure looks like this:
tbl.users tbl.issues
+--------+-----------+ +---------+------------+-----------+
| userid | real_name | | issueid | assignedid | creatorid |
+--------+-----------+ +---------+------------+-----------+
| 1 | test_1 | | 1 | 1 | 1 |
| 2 | test_2 | | 2 | 1 | 2 |
+--------+-----------+ +---------+------------+-----------+
Basically I want to write a query that will end in a results table looking like this:
(results table)
+---------+------------+---------------+-----------+--------------+
| issueid | assignedid | assigned_name | creatorid | creator_name |
+---------+------------+---------------+-----------+--------------+
| 1 | 1 | test_1 | 1 | test_1 |
| 2 | 1 | test_1 | 2 | test_2 |
+---------+------------+---------------+-----------+--------------+
My SQL looks like this at the moment:
SELECT
`issues`.`issueid`,
`issues`.`creatorid`,
`issues`.`assignedid`,
`users`.`real_name`
FROM `issues`
JOIN `users`
ON ( `users`.`userid` = `issues`.`creatorid` )
OR (`users`.`userid` = `issues`.`assignedid`)
ORDER BY `issueid` ASC
LIMIT 0 , 30
This returns something like this:
(results table)
+---------+------------+-----------+-----------+
| issueid | assignedid | creatorid | real_name |
+---------+------------+-----------+-----------+
| 1 | 1 | 1 | test_1 |
| 2 | 1 | 2 | test_1 |
| 2 | 1 | 2 | test_2 |
+---------+------------+-----------+-----------+
Can anyone help me get to the desired results table?
SELECT
IssueID,
AssignedID,
CreatorID,
AssignedUser.real_name AS AssignedName,
CreatorUser.real_name AS CreatorName
FROM Issues
LEFT JOIN Users AS AssignedUser
ON Issues.AssignedID = AssignedUser.UserID
LEFT JOIN Users AS CreatorUser
ON Issues.CreatorID = CreatorUser.UserID
ORDER BY `issueid` ASC
LIMIT 0, 30
On the general knowledge front, our illustrious site founder wrote a very nice blog article on this subject which I find myself referring to over and over again.
Visual Explanation of SQL Joins
Use this:
SELECT
`issues`.`issueid`,
`issues`.`creatorid`,
`creator`.`real_name`,
`issues`.`assignedid`,
`assigned`.`real_name`
FROM `issues` i
INNER JOIN `users` creator ON ( `creator`.`userid` = `issues`.`creatorid` )
INNER JOIN `users` assigned ON (`assigned`.`userid` = `issues`.`assignedid`)
ORDER BY `issueid` ASC
LIMIT 0 , 30
SELECT DISTINCT (i.issueid, i.creatorid, i.assignedid, u.real_name)
FROM issues i, users u
WHERE u.userid = i.creatorid OR u.userid = assignedid
ORDER BY i.issueid ASC
LIMIT 0 , 30
Not sure if the parenthesis are needed or not.
Does this work?
SELECT
i.issueid,
i.assignedid,
u1.real_name as assigned_name,
i.creatorid,
u2.real_name as creator_name
FROM users u1
INNER JOIN issues i ON u1.userid = i.assignedid
INNER JOIN users u2 ON u2.userid = i.creatorid
ORDER BY i.issueid
SELECT
i.issueid,
i.assignedid,
a.real_name,
i.creatorid,
c.real_name
FROM
issues i
INNER JOIN users c
ON c.userid = i.creatorid
INNER JOIN users a
ON a.userid = i.assignedid
ORDER BY
i.issueid ASC