Intermediate MySQL query: updating table column based on separate table column value - mysql

I have a table ticketdetails which contains a column with data that I want to copy to another table's column:
SELECT TicketID, MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID #might be unnecessary?
ORDER BY TicketID
The output looks like this:
I want the result of this query, "StartTime", to be supplied in my other table column, tickets.TimeScheduled, where the TicketID matches for both tables.
Right now I'm trying:
UPDATE tickets SET TimeScheduled = (
SELECT MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID
ORDER BY TicketID)
WHERE tickets.TicketID = ticketdetails.TicketID
I get this error:
#1054 - Unknown column 'ticketdetails.TicketID' in 'where clause'
I know that this column exists in my database. For some reason the query doesn't recognize the column. I think I need a JOIN or something, but I'm not the best with intermediate-advanced MySQL queries. Help is much appreciated.

Use a join:
UPDATE tickets AS t
JOIN (SELECT TicketID, MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID) AS d ON t.TicketID = d.TicketID
SET t.TimeScheduled = d.StartTime
The reason you're getting an Unknown column error is because the ticketdetails table only exists in the subquery, not in the main query.
If you want to set timeScheduled to NULL if there's no matching ticket in ticketdetails, change JOIN to LEFT JOIN.
BTW, there's no need for ORDER BY in the subquery.

You can do this with a correlated subquery:
UPDATE tickets
SET TimeScheduled = (SELECT MIN( td.StartTime ) StartTime
FROM ticketdetails td
WHERE td.TicketID = t.TicketID
);

Related

Update table row with values from same table column row

I want to update the values of column created_at with values of column updated_at, where value in the column created_at is 0000-00-00.
I tried the following query :
UPDATE tbl_message_types a
SET a.created_at = (
SELECT
c.updated_at
FROM
( SELECT b.updated_at
FROM tbl_message_types b
WHERE b.created_at LIKE '%0000-00-00%'
AND a.id = c.id ) AS c
)
AND a.created_at LIKE '%0000-00-00%';
But the result of the query is as follows :
> 1054 - Unknown column 'a.id' in 'where clause'
> Time: 0.008s
How can I modify the query ?
Your alias is out of place, but I would phrase this update using a join:
UPDATE tbl_message_types a
INNER JOIN UPDATE tbl_message_types b
ON a.id = b.id AND
COALESCE(b.created_at, '0000-00-00') != '0000-00-00'
WHERE COALESCE(a.created_at, '0000-00-00') = '0000-00-00';
Note that it is not clear how you ended up with datetime values of 0000-00-00 in your table. I am treating NULL the same way in my answer, though you may remove the call to COALESCE if you disagree.
I think you can do it in much simplified way.. without any join gimmicks; Why should you insist on a single query..? Do the select First, and update next. Try this..
select
value1 from tableName
where columnX like '%someThing%' and columnY = 'SomeValue' as value11;
update sametableName set someColumn= value11
where....

SQL query, check if cells with the same value in column A have the same value in column B

I have a table with a lot of columns and rows such as the below example :
I'm trying to find Orders that are partially complete, such that there is at least one Item Line record for the order that does have a Goods Issue Date value and one Item Line record for the order that does not have a Goods Issue Date value. I can easily get orders with no goods issue date at all, but I need to know the orders that have some item lines with a date and some without.
Looking at the sample data above, I should only see results for Order #1, because Orders 2,3, and 5 are all fully complete and Order 4 has not started yet.
SELECT
*
FROM
theTable t1
WHERE
t1.`Goods Issue Date` IS NULL
AND EXISTS ( SELECT
*
FROM
theTable t2
WHERE
t2.`Order` = t1.`Order`
AND t2.`Goods Issue Date` IS NOT NULL );
DEMO
You can also use a simple IN if Order is non-nullable
SELECT *
FROM theTable
WHERE `Goods Issue Date` IS NULL
AND `Order` IN (
SELECT `Order`
FROM theTable
WHERE `Goods Issue Date` IS NOT NULL
)
You first need to identify the bad orders. Here I've done this with a CTE (common table expression) for readability but it can be accomplished with a simple subquery in the join statement.
Once you have that, simply join the results back on the parent table.
WITH BadOrders AS (
SELECT *
FROM table
WHERE [Goods Issue Date] IS NULL)
SELECT table.*
FROM table
JOIN BadOrders ON table.Order = BadOrders.Order

Delete subquery with alias MySQL

I have a problem with this delete query:
DELETE r
FROM table AS r
WHERE r.stoptime IS NULL
and r.address IN
(select address from table where starttime <= r.starttime and stoptime > r.starttime)
I get the following error:
Error : You can't specify target table 'r' for update in FROM clause.
My goal is to delete records that the starttime is contained in another record but I got an error with the alias in the subquery.
Somebody know how to do this? Thanks in advance.
Try to use JOINS like this:
DELETE r
FROM `table` r
JOIN `table` t ON t.id = r.id
WHERE t.starttime <= r.starttime and t.stoptime > r.starttime
AND r.stoptime IS NULL

Unable to get the latest value added to Mysql table based on posted time

SELECT * FROM discussion_comments GROUP BY disc_id ORDER BY posted_date DESC
I have table example like given below:
CREATE TABLE example
(
id int(11),
cname varchar(11),
posted_date date,
posted_time varchar(20)
);
with values like:
INSERT INTO example
VALUES
(1,'abc','2015-03-26','04:25 PM'),
(1,'def','2015-03-27','04:30 PM'),
(2,'ghi','2015-03-11','02:25 AM'),
(2,'jkl','2015-03-15','12:25 PM');
and I am trying to get only the latest value added to the table for an id based on posted_date & posted_time fields.
The result I am trying to achieve is:
(1,'def','2015-03-27','04:30 PM')
(2,'jkl','2015-03-15','12:25 PM')
The query I tried is as follows:
SELECT * FROM `example GROUP BY id ORDER BY posted_date DESC
I am not getting the desired result. Where did I go wrong??
There are many ways and one way is left join
select e1.* from example e1
left join example e2 on e1.id = e2.id
and e1.posted_date < e2.posted_date where e2.id is null;
Or Uncorrelated Sub-query
select e1.* from example e1
join (
select id,max(posted_date) as posted_date from example group by id
)x
on x.id = e1.id and x.posted_date = e1.posted_date ;
if you want to sort desc date + time
select * from (select * from example order by STR_TO_DATE(CONCAT(posted_date,posted_time),'%Y-%m-%d%h:%i %p') desc) as xx group by id;
If you want to sort desc by just date
SELECT * FROM (select * from example order by posted_date desc) as ex group by id
IMHO storing as timestamp is better when dealing with date operations unless maybe you have more than one timestamp fields is same table.

Confused with UPDATE query. How to convert select to update with MySQL?

I have seen very similar if not same questions on here but my trials of trying to convert following query into an UPDATE statement failed.
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1
ORDER BY t.rank DESC
I want to update column of all results selected using the query above.
How can I convert this into an update statement?
Thank you.
This should do it:
update table
set column = 'somevalue'
where id in
(select id from (
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1) x)
not entirely sure but i think it's something like
update tblname set columname = value where tblname.columncompare = (select statement)
INSERT INTO table (id, value)
SELECT table.id, table.value
FROM table
JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column)
WHERE t.rank = 1
ORDER BY t.rank DESC
ON DUPLICATE KEY UPDATE value = VALUES(value)
Insert on duplicate to the rescue!
Basicly this allows you to do any SELECT as normal and then you prepend INSERT INTO and append ON DUPLICATE.
I guess that this query is made up, but what's the point of filtering and ordering the same column?