Query for selecting duplicates + finding lowest value - mysql

I have 3 tables in 3 different databaes; Currently the goal here is to find the duplicates unique ID in the three databases and then find the lowest price value of the duplicates unique ID.
Currently I'm using a INNER JOIN to query between only 2 database... Can anyone advise on how to add the third one?
set #a = (SELECT db1.tb1.var1 from db1.tb1
INNER JOIN db2.tb1 ON db2.tb1.var1 = db1.tb1.var1
UNION );
Also, once I have the #a variable set to the duplicate, I wanted to grab a secondary value here.
SELECT price
FROM db1.tb1
WHERE asin=#a
UNION ALL
SELECT price
FROM db2.tb1
WHERE asin=#a
UNION ALL
SELECT price
FROM db3.tb1
WHERE asin=#a
However, the result I'd get would return multiple rows (obviously), How do I query only for the MIN() number from this ?
Any help is appreciated.
Thanks,

Put your query into a subquery, and then use MIN() in the main query.
SELECT MIN(price)
FROM (
SELECT price
FROM db1.tb1
WHERE asin=#a
UNION ALL
SELECT price
FROM db2.tb1
WHERE asin=#a
UNION ALL
SELECT price
FROM db3.tb1
WHERE asin=#a) AS x

You can use order by and limit:
SELECT price
FROM db1.tb1
WHERE asin = #a
UNION ALL
SELECT price
FROM db2.tb1
WHERE asin = #a
UNION ALL
SELECT price
FROM db3.tb1
WHERE asin = #a
ORDER BY price
LIMIT 1;

Related

How sum certain duplicated data?

I have a list of ids, some ids can be duplicated.
How to sum values for the same id in one query?
SELECT SUM(`power`)
FROM `stats`
WHERE `template` IN (489191, 489191, 489100)
The template 489191 has power = 1 and 489100 has power = 0
so I need to get 2 as the result.
You need to join with table value data to get the desired number of rows e.g.:
select sum(stats.power)
from (
select 489191 as template union all
select 489191 union all
select 489100
) as vlist
join stats on vlist.template = stats.template
If you're using MySQL 8 or later you can use the values table value constructor instead of union all:
select sum(stats.power)
from (values
row(489191),
row(489191)
row(489100)
) as vlist(template)
join stats on vlist.template = stats.template

My sql select that has multiple row in the same criteria

I have mysql table like this
I want to get row that has minimum 2 or more than 2 (multiple) row only from this table, so the result would be like this
What do i do?
thank you
Use GROUP BY and HAVING clauses
SELECT t.* FROM my_table t
JOIN (
SELECT cust_id, MIN(transaction_no) AS transaction_no
FROM my_table
GROUP BY cust_id
HAVING COUNT(cust_id) > 1
) agg ON t.transaction_no = agg.transaction_no

combine two results into one result set mysql

I have two queries one will return data ordered by likes and in the user city the other one return data by the distance .
so if query 1 return : id 1,2,3 (order by likes)
and query 2 return : id 4,5,6 (order by distance)
i need the final set results to be 1,2,3,4,5,6
i've tried to do union between the two queries but it's not working. any other suggestions ?
You can use left join or union according to this link.
Union ALL also works like you can see here.
Example: SELECT 1 UNION ALL SELECT 2
the solution was to put a limit to each query then the union will work correct :
(SELECT DISTINCT ID, 'a' as type,... FROM table1 GROUP BY ID ORDER BY likesDESC limit 50) union all( SELECT DISTINCT ID, 'b' as type,....FROM table1 GROUP BY ID ORDER BY distance limit 50) order by type asc.

mysql select rows with same ids and preserve their order?

just a quick question:
i have to have one single query that has multiple rows - some rows are identicle - and the order of rows must be preserved in the result -
some idea of what im refering to:
SELECT id,date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY id=1 DESC,id=2 DESC,id=1 DESC,id=3 DESC;
unfortunately mysql result is this:
1,2,3
not 1,2,1,3
it removes the duplicate which i have to have in my result to display in multiple panels on the same webpage -
i really dont want to loop thru each id one by one to get them the way i want to display -
is there a way to actually have one single query that will preserve the order and pull out rows based on request whether its unique or not -
Your query as it stands will never work, because duplicate values in a list of values of an IN clause are ignored. The only way to make this work is by using UNION ALL:
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 2
UNION ALL
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 3;
But to be frank, I suspect your data model so far past screwed it's unusable.
try
SELECT
id,
date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY FIND_IN_SET(id, '1,2,1,3')
Another scrupulous way to answer a suspicious question:
SELECT
items.id,
items.date
FROM
items
JOIN
( SELECT 1 AS id, 1 AS ordering
UNION ALL
SELECT 2, 2
UNION ALL
SELECT 1, 3
UNION ALL
SELECT 3, 4
) AS auxilary
ON
auxilary.id = items.id
ORDER BY
auxilary.ordering
Another approach (untested, but should give you the idea):
CREATE TEMPORARY TABLE tt (id INT, ai int unsigned auto_increment primary key);
INSERT INTO tt (id) VALUES (1), (2), (1), (3);
SELECT
id,
date
FROM items JOIN tt USING (id)
ORDER BY tt.ai;
keeps the given order.
If you want to include the records with id=1 and the order doesn't matter as long as you get them, you can split your query into two queries, one for (1,2,3) union all the other query for id=1 or just do:
... In (1,2)
Union all
... In (1,3)
Example:
Select * from
(Select case id when 1 then 1 when 2 then 2 as pseudocol, othercolumns
From table where Id in (1,2)
Union all
Select case id when 1 then 3 when 3 then 4 as pseudocol, othercolumns
From table where Id in (1,3)) t order by pseudocol
Instead of doing what you are trying to, just select the unique rows you need. In the frontend code, store each unique row once in a key=>value structure, where key is the item ID and value is whatever data you need about that item.
Once you have that you can use frontend logic to output them in the desired order including duplicates. This will reduce the amount of redundant data you are trying to select.
For example This is not usable code - exact syntax required depends on your scripting language
-- setup a display order
displayOrder= [1,2,1,3];
-- select data from database, order doesn't matter here
SELECT id,date
FROM items
WHERE id IN (displayOrder);
-- cache the results in a key=> value array
arrCachedRows = {};
for (.... each db row returned ...) {
arrCachedRows[id] = date;
}
-- Now output in desired order
for (listIndex in displayOrder) {
-- Make sure the index is cached
if (listIndex exists in arrCachedRow) {
echo arrCachedRows[listIndex ];
}
}
If you must persist in using UNION despite my warnings
If you go against the above recommendation and absolutely MUST have them back in 1 query in that order then add on an additional row which will enforce the row order. See below query where I use variable #subIndex to add an incrementing value as subIndex. This in turn lets you reorder by that and it'll be in the requested order.
SELECT
i.*
FROM (
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 2
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 3
) AS i,(SELECT #subIndex:=0) v
ORDER BY i.subIndex
Or a slightly cleaner version that keeps item selection until the outside and hides the subindex
SELECT
items.*
FROM items
-- initialise variable
INNER JOIN (SELECT #subIndex:=0) v
-- create a meta-table with the ids desired in the order desired
INNER JOIN (
SELECT #subIndex:=#subIndex+1 AS subIndex, 1 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 2 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 1 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 3 AS id
) AS i
ON i.id = items.id
-- order by the subindex from i
ORDER BY i.`subIndex` ASC

MySQL: Counting column from different tables on a certain timeframe

I have the following query:
SELECT SUM(COUNTED) AS TCOUNTED
FROM (SELECT COUNTED FROM `clicks`.`t1`
UNION ALL
SELECT COUNTED FROM `clicks`.`t2`
UNION ALL
SELECT COUNTED FROM `clicks`.`t3`
) AS TMP
Where and how do I add a time constraint? I want it to count only between certain dates... Sorry for the MySQL noobness.
Thanks!
SELECT SUM(COUNTED) AS TCOUNTED
FROM (SELECT COUNTED FROM `clicks`.`t1` WHERE somedatecol BETWEEN somedate AND somedate
UNION ALL
SELECT COUNTED FROM `clicks`.`t2` WHERE somedatecol BETWEEN somedate AND somedate
UNION ALL
SELECT COUNTED FROM `clicks`.`t3` WHERE somedatecol BETWEEN somedate AND somedate
) AS TMP`
http://dev.mysql.com/doc/refman/5.0/en/select.html
I would think your best bet is to include the where clause inside each sub-select before the UNION statements.
SELECT SUM(COUNTED) AS TCOUNTED FROM
(SELECT COUNTED FROM clicks.t1 WHERE <fieldname> BETWEEN '<date1>' AND '<date2>'
UNION ALL
SELECT COUNTED FROM clicks.t2 WHERE <fieldname> BETWEEN '<date1>' AND '<date2>'
UNION ALL
SELECT COUNTED FROM clicks.t3 WHERE <fieldname> BETWEEN '<date1>' AND '<date2>')
AS TMP;
Of course it as all relative to what you are trying to accomplish with the query.