Select query with condition for the column from the second table - ms-access

I have 2 tables (THour_IN and THour_OUT) that have identical schemas:
Columns for THour_IN: Name|date|HourIN
Colums for THour_OUT: Name|date|HourOUT
I make query:
SELECT THour_IN.Name, THour_IN.date, THour_IN.HourIN, THour_OUT.HourOUT FROM THour_IN LEFT JOIN THour_OUT ON (Hour_IN.Name = THour_OUT.Name) AND (Hour_IN.date = THour_OUT.date);
But this is not correct in my case, because I have multiple rows wtih the same date in the tables. The result is:
Name date HourIN HourOUT
AAA 24/11/2013 17:33:06 20:33:27
AAA 24/11/2013 17:33:06 16:36:06
AAA 24/11/2013 07:33:27 20:33:27
AAA 24/11/2013 07:33:27 16:36:06
BBB 18/11/2013 16:36:06
BBB 19/11/2013 07:33:30
BBB 21/11/2013 07:29:24 08:33:22
BBB 22/11/2013 07:33:30 16:34:53
It should be for date 24/11/2013 First HourIN(07:33:27) with Fisrt HourOUT (16:36:06), Second HourIN (17:33:06) with Second HourOUT (20:33:06) Any ideas?

Build segments, then intersect segments.
SELECT
P1.Name, P1.date, P1.HourIN, P1.HourOUT
FROM (
SELECT
I.Name, I.date, I.HourIN, O.HourOUT
FROM
THour_IN AS I
LEFT JOIN THour_OUT AS O
ON (I.Name = O.Name) AND (I.date = O.date)
AND I.HourIN < H.HourOUT
) AS P1
INNER JOIN (
SELECT
I.Name, I.date, I.HourIN, O.HourOUT
FROM
THour_IN AS I
LEFT JOIN THour_OUT AS O
ON (I.Name = O.Name) AND (I.date = O.date)
AND I.HourIN < H.HourOUT
) AS P2
ON P1.name = P2.name AND P1.date = P2.date
AND P1.HourIN <> P2.HourIN and P1.HourOUT <> P2.HourOUT
AND P1.HourOUT > P2.HourIN
AND (P1.HourIN = P2.HourIN AND P1.HourOUT < P2.HourOUT
OR P1.HourIN > P2.HourIN AND P1.HourOUT = P2.HourOUT)

You could use something like so:
SELECT
t.Name,
t.Date,
t.HourIN, (
SELECT Top 1 HourOut
FROM THourOUT o
WHERE o.Name=t.Name AND o.Date=t.date And o.HourOUT>t.HourIN
ORDER BY o.HourOUT,o.ID ) AS HrOut
FROM THourIN AS t
ORDER BY t.Date, t.HourIN;
Note that I have added an ID to the OUT table to ensure that top 1 does not return duplicates.
Here is an example of inserting missing values. It depends on a Numbers table containing integers from 0 or 1 to the highest number of missing values. A number table is useful in many ways.
INSERT INTO thourin
(name,
[date])
SELECT q.name,
q.DATE
FROM (SELECT Outs.name,
Outs.DATE,
Outs.countofout,
Ins.countofin
FROM (SELECT o.name,
o.DATE,
Count(o.name) AS CountOfOut
FROM thourout o
GROUP BY o.name,
o.DATE) AS Outs
LEFT JOIN (SELECT t.name,
t.DATE,
Count(t.name) AS CountOfIn
FROM thourin t
GROUP BY t.name,
t.DATE) AS Ins
ON ( Outs.name = Ins.name )
AND ( Outs.DATE = Ins.DATE )
WHERE (( ( Ins.countofin ) <> [countofout]
OR ( Ins.countofin ) IS NULL ))) AS q,
numbers AS n
WHERE (( ( n.counter ) > 0
AND ( n.counter ) <= [countofout] - [countofin] ))

Related

A SQL statement to return a count and a max

I use Spring Boot with Hibernate. Currently I have 3 separate requests to a database:
fetch all specific (with some WHERE conditions) data from table aaa
fetch all specific (with some WHERE conditions) data from table bbb
fetch max date of record that is found by WHERE clause with the same conditions from points 1 and 2.
Statement #1
SELECT count(a.id) as dateTo
from (
SELECT a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
) allDates
Statement #2
SELECT count(b.id) as dateTo
from (
SELECT b.date_to
FROM bbb b
WHERE tw.warehouse.id = :warehouseId
AND tw.status = 'AVAILABLE'
) allDates
Statement #3
SELECT MAX(date_to) as dateTo
from (
SELECT a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
UNION
SELECT b.valid_to as date_to
FROM bbb b
WHERE b.warehouse_id = 222
AND tw.status = 'AVAILABLE'
) allDates
Is it possible to do all this with one statement? I use MySql 5.7 so CTE is not available.
My code in Spring:
final long numberOfa = ...
final long numberOfB = ...
final LocalDate maxDate = ...
Expected result:
final MyObjectWithAllThreeValues myObject = repository.getAllDataWithOneQuery
You can store a flag in the subqueries (called "which_tab"), then use a CASE expression within a SUM aggregation function to count your rows.
SELECT MAX(date_to) AS dateTo,
SUM(CASE WHEN which_tab = 'a' THEN 1 END) AS count_a_id,
SUM(CASE WHEN which_tab = 'b' THEN 1 END) AS count_b_id
from (
SELECT 'a' AS which_tab, a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
UNION ALL
SELECT 'b' AS which_tab, b.valid_to AS date_to
FROM bbb b
WHERE b.warehouse_id = 222
AND tw.status = 'AVAILABLE'
) allDates
Note: if your rows from the two subqueries you apply the UNION on do not overlap, it's better to use UNION ALL as it avoids an additional unnecessary aggregation.
All queries return a single row, because you aggregate all rows without any GROUP BY. You can hence do both aggregations and then cross join the two result rows:
SELECT
a_agg.cnt AS count_a,
b_agg.cnt AS count_b,
GREATEST(a.max_date, b.max_date) AS max_date
FROM
(
SELECT COUNT(*) AS cnt, MAX(a.date_to) AS max_date
FROM aaa a
JOIN ramp r ON r.id = a.ramp_id
JOIN warehouse w ON w.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= TIMESTAMP '2022-08-20 00:00:00'
) a_agg
CROSS JOIN
(
SELECT COUNT(*) AS cnt, MAX(b.date_to) AS max_date
FROM bbb b
WHERE b.warehouse.id = :warehouseId
AND b.status = 'AVAILABLE'
) b_agg;

MySQL derived table with join

In the following query I'm having a problem when it comes to returning the right value for count2.
What I need is to get the number of rows from table2 which could easily be done by using a derived table t:
SELECT name,
(SELECT COUNT(*) FROM `table1`) AS count1,
(SELECT COUNT(*) FROM (
SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
) t AS count2,
(SELECT SUM(a) FROM `table3`) AS count3
FROM `profiles` prf
WHERE 1=1
AND prf.user = 1
The problem is that the WHERE t2.user = prf.user statement fails as the prf table is outside the subquery's scope.
How can I achieve the above?
EDIT: I'm adding the actual query in case it's helpful for getting a better grasp:
SELECT PRF.BranchID, PRF.user_id, CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
( SELECT COUNT(*) FROM Actions A JOIN Requests R ON R.RequestID=A.RequestID WHERE A.ActionStatus = 302 AND A.UserOwner = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS energeies,
( SELECT COUNT(DISTINCT RPP.RequestID) FROM VW_Xartofylakio_Synergati VV JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID JOIN Requests R ON R.RequestID = RPP.RequestID WHERE VV.CurrUsr = PRF.user_id AND R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10' ) AS zitiseis_eidikes,
( SELECT COUNT(DISTINCT(CustomerID)) FROM Demo_Orders_M WHERE DemoOrderStatus=253 AND USER=PRF.user_id AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS endiaferomenoi,
( SELECT COUNT(*) AS cnt FROM Demo_Orders_M DOM JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID WHERE DOM.User = PRF.user_id AND DOM.DemoOrderStatus = 253 AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19' GROUP BY DOM.CustomerID, DOM.User HAVING COUNT(*) > 1 ) AS anakykl_endiaf,
( SELECT COUNT(*) FROM Demo_Orders_M DOM WHERE DOM.`User`=PRF.user_id AND DemoOrderStatus = 253 AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS epideixeis,
( SELECT COUNT(DISTINCT(DOD.PropertyID)) AS PropertyID FROM Demo_Orders_M DOM JOIN Demo_Orders_D DOD ON DOM.DemoOrderID = DOD.DemoOrderID JOIN Actions A ON DOD.DemoOrderID = A.DemoOrderID WHERE DOM.DemoOrderStatus = 253 AND DOM.User = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS monadika_akinita
FROM tbl_profiles PRF
WHERE 1=1
AND PRF.user_id IN (
SELECT a.user_id FROM tbl_profiles a WHERE a.user_id IN ('248','1159','486','183')
OR a.GroupID IN (SELECT b.GroupID FROM L_Groups b WHERE b.ManagerID IN ('248','1159','486','183'))
)
ORDER BY PRF.user_id
The subquery I'm referring to is the one that returns the result as anakykl_endiaf.
I suspect it is not because of prf table, it is because of t2 table... There are no restrictions to use outer alias in inner subqueries because there are such a thing like correlated subquery. Your problem is that you have the opposite case here: you are referring inner alias in outer query.
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
Why are you selecting count twice here? You can change to this:
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2 WHERE t2.user = prf.user))
or this:
(SELECT COUNT(*)
FROM `table2` t2 WHERE t2.user = prf.user)
A suggestion to try.
You have sub queries in the SELECT, and in this case they must each only return a single row. For some reason (which we can't really tell without test data) one of these is returning more than 1 row, hence failing.
As an interim step, change the query to join against the sub queries, which should make it more obvious when there are duplicates (and may also be quite a bit more efficient, depending on the data).
Something like this (not tested so probably a few typos):-
SELECT PRF.BranchID,
PRF.user_id,
CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
ar.energeies,
vrr.zitiseis_eidikes,
m.endiaferomenoi,
ae.anakykl_endiaf,
d.epideixeis,
ddd.monadika_akinita
FROM tbl_profiles PRF
LEFT OUTER JOIN
(
SELECT A.UserOwner AS DomUser, COUNT(*) AS energeies
FROM Actions A
JOIN Requests R ON R.RequestID=A.RequestID
WHERE A.ActionStatus = 302
AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY A.UserOwner
) ar
ON ar.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT VV.CurrUsr AS DomUser, COUNT(DISTINCT RPP.RequestID) AS zitiseis_eidikes
FROM VW_Xartofylakio_Synergati VV
JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID
JOIN Requests R ON R.RequestID = RPP.RequestID
WHERE R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY VV.DomUser
) vrr
ON vrr.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT `USER` AS DomUser, COUNT(DISTINCT(CustomerID)) AS endiaferomenoi
FROM Demo_Orders_M
WHERE DemoOrderStatus=253
AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DomUser
) m
ON PRF.user_id = m.DomUser
LEFT OUTER JOIN
(
SELECT DOM.CustomerID, DOM.`User` AS DomUser, COUNT(*) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.CustomerID, DOM.DomUser
HAVING COUNT(*) > 1
) ae
ON PRF.user_id = ae.DomUser
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(*) AS epideixeis
FROM Demo_Orders_M DOM
WHERE DemoOrderStatus = 253
AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DOM.DomUser
) d
EDIT
If you just want a count of the number of customerID fields for a user in the anakykl_endiaf field then change it to doing a count of distinct customerIDs. Ie, for the above query I have done change it to:-
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(DISTINCT DOM.CustomerID) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.DomUser
HAVING COUNT(*) > 1
) ae

MySQL: Grouped by hour, need to show all hours, null where no data

Here's the query:
SELECT h.idhour, h.`hour`, outnumber, count(*) as `count`, sum(talktime) as `duration`
FROM (
SELECT
`cdrs`.`dcustomer` AS `dcustomer`,
(CASE
WHEN (`cdrs`.`cnumber` like "02%") THEN '02'
WHEN (`cdrs`.`cnumber` like "05%") THEN '05'
END) AS `outnumber`,
FROM_UNIXTIME(`cdrs`.`start`) AS `start`,
(`cdrs`.`end` - `cdrs`.`start`) AS `duration`,
`cdrs`.`talktime` AS `talktime`
FROM `cdrs`
WHERE `cdrs`.`start` >= #_START and `cdrs`.`start` < #_END
AND `cdrs`.`dtype` = _LATIN1'external'
GROUP BY callid
) cdr
JOIN customers c ON c.id = cdr.dcustomer
LEFT JOIN hub.hours h ON HOUR(cdr.`start`) = h.idhour
WHERE (c.parent = _ID or cdr.dcustomer = _ID or c.parent IN
(SELECT id FROM customers WHERE parent = _ID))
GROUP BY h.idhour, cdr.outnumber
ORDER BY h.idhour;
The above query results skips the hours where there is no data, but I need to show all hours (00:00 to 23:00) with null or 0 values. How can I do this?
SELECT h.idhour
, h.hour
,IFNULL(outnumber,'') AS outnumber
,IFNULL(cdr2.duration,0) AS duration
,IFNULL(output_count,0) AS output_count
FROM hub.hours h
LEFT JOIN (
SELECT HOUR(start) AS start,outnumber, SUM(talktime) as duration ,COUNT(1) AS output_count
FROM
(
SELECT cdrs.dcustomer AS dcustomer
, (CASE WHEN (cdrs.cnumber like "02%") THEN '02' WHEN (cdrs.cnumber like "05%") THEN '05' END) AS outnumber
, FROM_UNIXTIME(cdrs.start) AS start
, (cdrs.end - cdrs.start) AS duration
, cdrs.talktime AS talktime
FROM cdrs cdrs
INNER JOIN customers c ON c.id = cdrs.dcustomer
WHERE cdrs.start >= #_START and cdrs.start < #_END AND cdrs.dtype = _LATIN1'external'
AND
(c.parent = _ID or cdrs.dcustomer = _ID or c.parent IN (SELECT id FROM customers WHERE parent = _ID))
GROUP BY callid
) cdr
GROUP BY HOUR(start),outnumber
) cdr2
ON cdr2.start = h.idhour
ORDER BY h.idhour
You need a table with all hours, nothing else.
Then use LEFT JOIN with the hours table on the "left" and your current query on the "right":
SELECT b.*
FROM hours h
LEFT JOIN ( ... ) b ON b.hr = h.hr
WHERE h.hr BETWEEN ... AND ...
ORDER BY hr;
Any missing hours will be NULLs in b.*.

MySQL - Combining multiple queries + counts

I'm attempting to combine a few queries and can't seem to nail it down. I was wondering if someone could point me in the right direction.
Here are the statements:
SELECT
I.id,
I.custname,
I.custemail,
I.sku,
DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
FROM images I
WHERE I.stat = 0
SELECT
COUNT(*) AS total1
FROM images
WHERE stat = 1 AND sku = ?
SELECT
COUNT(*) AS total2
FROM images
WHERE stat = 1
AND sku IN (SELECT subsku FROM combo WHERE sku = ?)
Right now I'm using the 3 separate queries and am using code to add the two totals and display them. But I now need to be able to sort by the sum of the totals, so I'd like to get all of that data into one statement.. something like:
SELECT
I.id,
I.custname,
I.custemail,
I.sku,
DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts,
SUM(total1+total2)
FROM images I
WHERE I.stat = 0
But I'm unsure how to do that. I tried the code below, but it failed:
SELECT
I.id,
I.custname,
I.custemail,
I.sku,
DATE_FORMAT(FROM_UNIXTIME(I.ts),'%l:%i:%s %p, %c/%e/%Y') AS ts,
(
SELECT COUNT(*) AS total1 FROM images WHERE stat = 1 AND (
sku IN (
SELECT subsku FROM combo WHERE sku = I.sku
) OR sku = I.sku)
) AS skuct
FROM images I
WHERE stat = 0
Any help would be greatly appreciated. Many thanks!
UPDATE
First off thanks to everyone who has offered assistance. I've been working on the query and think I'm getting closer, but I'm now hitting a 'subquery returns more than 1 row' error:
SELECT
I.id,
I.custname,
I.custemail,
I.sku,
DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts,
(
SELECT COUNT(*)
FROM images
WHERE stat = 1
AND sku = I.sku
OR sku IN(
SELECT subsku FROM combo WHERE sku = I.sku
)
GROUP BY sku
) AS total
FROM images I
WHERE stat = 0
The problem is that the subquery SELECT subsku FROM combo WHERE... returns a resultset (0+ rows) vs a scalar. If I can figure out that part, I think this will work.
Select I.id, I.custname, I.custemail, I.sku
, DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
, (
Select Sum( Case
When I1.sku = ? Then 1
When I1.sku In( Select subsku From combo As S1 Where S1.sku = ? ) Then 1
Else 0
End ) As Total
From images As I1
Where I1.stat = 1
) As Total
From images As I
Where stat = 0
Another solution
Select I.id, I.custname, I.custemail, I.sku
, DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
, (
Select Count(*)
From images As I1
Where I1.stat = 1
And (
I1.sku = ?
Or I1.sku In ( Select subsku From combo As S1 Where S1.sku = ? )
)
) As Total
From images As I
Where stat = 0
Addition
Another possible solution:
Select I.id, I.custname, I.custemail, I.sku
, DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
, (
Select Sum( Cnt )
From (
Select Count(*) As Cnt
From images As I1
Left Join combo As C1
On C1.sku = I1.sku
Where I1.stat = 1
And I1.sku = ?
And C1.PrimaryKeyCol Is Null
Union All
Select Count( Distinct I1.PrimaryKeyCol )
From images As I1
Join combo As C1
On C1.sku = I1.sku
Where I1.stat = 1
And I1.sku = ?
) As Z
) As Total
From images As I
Where stat = 0
Edit
If you are looking for the count by image in which you correlate the counts to the outer table images sku column, that's entirely different. For that, I would use a derived table:
Select I.id, I.custname, I.custemail, I.sku
, DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
, Counts.Total
From images As I
Join (
Select Z.sku, Sum(Z.Cnt) As Total
From (
Select I1.sku, Count(*) As Cnt
From images As I1
Left Join combo As C1
On C1.sku = I1.sku
Where I1.stat = 1
And C1.PrimaryKeyCol Is Null
Group By I1.sku
Union All
Select I1.sku, Count( Distinct I1.PrimaryKeyCol )
From images As I1
Join combo As C1
On C1.sku = I1.sku
Where I1.stat = 1
Group By I1.sku
) As Z
Group By Z.sku
) As Counts
On Counts.sku = I.sku
Where stat = 0
Obviously in all cases, replace PrimaryKeyCol with the name of the actual primary key column of the images table.
Have you considered changing the WHERE logic to perform the count in one.
Assuming the two counts are mutually exclusive you could just OR the two conditions.
Use the cross join . . .
select t1.*, t2.total1, t3.total2
from
(
SELECT I.id, I.custname, I.custemail, I.sku,
DATE_FORMAT(FROM_UNIXTIME(I.ts), '%l:%i:%s %p, %c/%e/%Y') AS ts
FROM images I
WHERE I.stat = 0
) t1
cross join
(
SELECT COUNT(*) AS total1
FROM images
WHERE stat = 1 AND sku = ?
) t2
cross join
(
SELECT COUNT(*) AS total2
FROM images
WHERE stat = 1 AND sku IN (SELECT subsku FROM combo WHERE sku = ?)
) t3
You might be able to make this more efficient, since they are all going after the same table. A single aggregation with a case statement per WHERE clause would probably be more efficient.

MySQL Update Inner Join Aliases

I'm trying to run this query:
UPDATE anothertable
INNER JOIN (SELECT *,
LEAST(table1.from_price, table2.from_price, table3.from_price) AS cheapestPrice
FROM (SELECT * FROM table1 v WHERE hotelid >= 1
UNION
SELECT * FROM table2 c WHERE hotelid >= 1
UNION
SELECT * FROM table3 k WHERE hotelid >= 1) AS temp
GROUP BY temp.hotelid, temp.country) AS i ON anothertable.id = i.hotelid
AND anothertable.country = i.country
SET price = i.cheapestPrice,
op = i.to
However I cannot get the LEAST function to get access to a field called "from_price".
Ideas?
You should use Min instead of Least:
Update anothertable
Join (
Select hotelid, country, to
, Min(from_price) AS cheapestPrice
From (
Select hotelid, country, from_price, to
From table1 v
Where hotelid >= 1
Union
Select hotelid, country, from_price, to
From table2 c
Where hotelid >= 1
Union
Select hotelid, country, from_price, to
From table3 k
Where hotelid >= 1
) AS temp
Group By temp.hotelid, temp.country, temp.to
) As i
On anothertable.id = i.hotelid
And anothertable.country = i.country
Set price = i.cheapestPrice
, op = i.to
Edit
As pointed out in comments, I omitted the to column from the inner temp query. However, it occurs to me that it isn't clear how to should be included because you are using an awful feature of MySQL with respect to declaring the Group By columns. I'm assuming that you need to include to in the Group By however if that is not the case, you should be explicit about what aggregate function it should use on the to column.
Here's an alternate where I use Min on the to column:
Update anothertable
Join (
Select temp.hotelid, temp.country
, Min(temp.to) As to
, Min(temp.from_price) AS cheapestPrice
From (
Select v.hotelid, v.country, v.from_price, v.to
From table1 v
Where hotelid >= 1
Union
Select c.hotelid, c.country, c.from_price, c.to
From table2 c
Where hotelid >= 1
Union
Select k.hotelid, k.country, k.from_price, k.to
From table3 k
Where hotelid >= 1
) AS temp
Group By temp.hotelid, temp.country
) As i
On anothertable.id = i.hotelid
And anothertable.country = i.country
Set price = i.cheapestPrice
, op = i.to