JOIN 5 Database in MYSQL - mysql

I have 5 Database, Let say their name is A B C D E
All database have the same table / structure / field
I want to get result from 5 database using table SMSOutgoing and the field is uid
It look like this :
SELECT * OR JOIN 5 database A B C D E F
FROM `table` SMSOutgoing
WHERE uid = 1
Not all the database have uid=1, it need to display which database have the result
I run SMS Gateway, each phone / 1 number using 1 database, thats why there is so many different database.
I spent hours to solve it but always error, I think i follow the wrong guide (JOIN multiple table in 1 database)
I'm Lost, please Help and Thank You

Sounds like you want to list the databases out that contain uid = 1 in the SMSOutgoing table. If so, you should be able to use UNION:
SELECT DISTINCT 'DatabaseA' WhichDb
FROM DatabaseA.SMSOutgoing
WHERE uid = 1
UNION
SELECT DISTINCT 'DatabaseB' WhichDb
FROM DatabaseB.SMSOutgoing
WHERE uid = 1
UNION
...
UNION
SELECT DISTINCT 'DatabaseF' WhichDb
FROM DatabaseF.SMSOutgoing
WHERE uid = 1
I used DISTINCT in case you could have multiple uid in the same table -- that may be unnecessary.
EDIT: From your comments, it sounds like you just want the results:
SELECT *
FROM DatabaseA.SMSOutgoing
WHERE uid = 1
UNION
SELECT *
FROM DatabaseB.SMSOutgoing
WHERE uid = 1
UNION
...
UNION
SELECT *
FROM DatabaseF.SMSOutgoing
WHERE uid = 1
You may need to use UNION ALL if you might have duplicates...

Related

What's an easy way to perform this complicated SELECT query?

Given these entries in a table table:
user entry
A 1
A 2
A 5
A 6
B 1
B 2
B 3
B 4
B 5
B 6
C 1
C 4
D 1
D 2
D 5
D 6
D 7
D 9
And we have a subset entries_A to work with, which is the array [1,2,5,6].
Problems:
Find all users that have the same entries [1,2,5,6] and more, e.g. [1,2,5,6,7] or [1,2,3,5,6].
Find all users that have a lot of the same entries (and more), e.g. [1,2,5,9] or [2,5,6,3].
The best solution to the first problem I could come up with, is the following select query:
SELECT DISTINCT user AS u FROM table WHERE EXISTS (SELECT * FROM table WHERE entry=1 AND user=u)
AND EXISTS(SELECT * FROM table WHERE entry=2 AND user=u)
AND EXISTS(SELECT * FROM table WHERE entry=5 AND user=u)
AND EXISTS(SELECT * FROM table WHERE entry=6 AND user=u)
On the other hand, I get a feeling there's some algebraic vector-problem lurking below the surface (especially for problem two) but I can't seem to wrap my head around it.
All ideas welcome!
I think the easiest way to perform this type of query is using aggregation and having. Here is an example.
To get A's that have exactly those four elements:
select user
from table
group by user
having sum(entry in (1,2,5,6)) > 0 and
count(distinct entry) = 4;
To get A's that have those four elements and perhaps others:
select user
from table
group by user
having sum(entry in (1,2,5,6)) > 0 and
count(distinct entry) >= 4;
To order users by the number of matches they have and the number of other matches:
select count(distinct case when entry in (1, 2, 5, 6) then entry end) as Matches,
count(distinct case when entry not in (1, 2, 5, 6) then entry end) as Others,
user
from table
group by user
order by Matches desc, Others;
For the first problem:
SELECT user FROM (
SELECT
DISTINCT user
FROM
table
WHERE entry IN (1,2,5,6)
) a JOIN table b ON a.user = b.user
GROUP BY a.user
HAVING COUNT(*) >= 4
For the second problem just decrease the count in the having clause.
This is how I would to your first query (though I think Gordon Linoff's answer is more efficient):
select distinct user from so s1
where not exists (
select * from so s2 where s2.entry in (1,2,5,6)
and not exists (
select * from so s3 where s2.entry = s3.entry and s1.user = s3.user
)
);
For the second problem, you would need to specify what a lot should mean... three, four, ...

MySQL select from custom set and compare with table data

Hi I'm trying to solve which elements doesn't exists in my database. In order to do so I want to compare list of integers (output from external script) with data in table. How to do such thing like:
SELECT * FROM (1,1,2,3,5,8,13...) l WHERE l NOT IN (select id from table1);
This is probably best done with a left outer join. But, your problem is creating the table of constants:
SELECT *
FROM (select 1 as id union all select 2 union all select 3 union all select 5 union all
select 8 union all select 13 union all select 21 . . .
) ids
where ids.id NOT IN (select id from table1);
This can have odd behavior, if table1.id is ever NULL. The following works more generally:
SELECT *
FROM (select 1 as id union all select 2 union all select 3 union all select 5 union all
select 8 union all select 13 union all select 21 . . .
) ids left outer join
table1 t1
on ids.id = t1.id
where t1.id is null;
EDIT:
The size of a MySQL query is dictated by the parameter max_packet_size (see here). The most recent version has a limit of 1 Gbyte. You should be able to fit 18,000 rows of:
select <n> union all
into that limit, quite easily. Gosh, I don't even think it would be 1 megabyte. I would say, though, that passing a list of 18,000 ids through the application seems inefficient. It would be nice if one database could just pull the data from the other database, without going through the application.
If your set to compare is huge I'd recommend you to create a temporary table myids with the only column id, put there all your 18K values and run query like that:
select id from myids where myids.id not in (select id from table1);

SQL query return what's NOT in table [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL: find missing IDs in a table
getting values which dont exist in mysql table
Just wondering, is it possible to have a query that somehow tells you the values it did not find in a table?
So if I had a query SELECT * FROM mytable WHERE id IN (1,2,3,4,5,6,7,8,9) and only 2,3,6,7,9 was returned. I wouldd like to know that 1,4,5,8 were not found.
It will be a little hard to do a manual comparision, because this is going to be run over apx 2,000+ rows in a table (the id's are going to be provided via a csv file which can be copied into the query)
Thanks in advance
This is probably silly, but what about creating a temporary table containing all your IDs from which you'll substract the result of your SELECT query ?
Untested, but in theory:
Table 1:
+----+-----+
| id | num |
+----+-----+
Table 2:
+----+
| id |
+----+
Table 1 contains the data you're looking for (and num is any field containing any data)
Table 2 contains the IDs from the CSV
SQL:
SELECT COUNT(`Table1`.`num`) AS `count`
FROM `Table1`
LEFT JOIN `Table2` ON `Table1`.`id` = `Table2`.`id`
WHERE `count` = 0
Quick solution, open your csv file, replace all comma's with " union select " put select in front of that line and use it as the first line of the query at the bottom query.
So 1,2,3 becomes
Select 1 union select 2 union select 3
Use this in the query below
Select 1 union select 2 union select x -- replace this line with the line generated from your csv
Except
(
Select id from mytable
)
What about:
SELECT *
FROM (select 1 as f
UNION
SELECT 2 as f
UNION
SELECT 3 as f
UNION
SELECT 4 as f
UNION
SELECT 5 as f
UNION
SELECT 6 as f
UNION
SELECT 7 as f
UNION
SELECT 8 as f
UNION
SELECT 9 ) as s1
WHERE f NOT IN (SELECT id FROM mytable);

Adding one extra row to the result of MySQL select query

I have a MySQL table like this
id Name count
1 ABC 1
2 CDF 3
3 FGH 4
using simply select query I get the values as
1 ABC 1
2 CDF 3
3 FGH 4
How I can get the result like this
1 ABC 1
2 CDF 3
3 FGH 4
4 NULL 0
You can see Last row. When Records are finished an extra row in this format
last_id+1, Null ,0 should be added. You can see above. Even I have no such row in my original table. There may be N rows not fixed 3,4
The answer is very simple
select (select max(id) from mytable)+1 as id, NULL as Name, 0 as count union all select id,Name,count from mytable;
This looks a little messy but it should work.
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM
(
SELECT 1 as ID
UNION
SELECT 2 as ID
UNION
SELECT 3 as ID
UNION
SELECT 4 as ID
) a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID IN (1,2,3,4)
UPDATE 1
You could simply generate a table that have 1 column preferably with name (ID) that has records maybe up 10,000 or more. Then you could simply join it with your table that has the original record. For Example, assuming that you have a table named DummyRecord with 1 column and has 10,000 rows on it
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM DummyRecord a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID >= 1 AND
a.ID <= 4
that's it. Or if you want to have from 10 to 100, then you could use this condition
...
WHERE a.ID >= 10 AND
a.ID <= 100
To clarify this is how one can append an extra row to the result set
select * from table union select 123 as id,'abc' as name
results
id | name
------------
*** | ***
*** | ***
123 | abc
Simply use mysql ROLLUP.
SELECT * FROM your_table
GROUP BY Name WITH ROLLUP;
select
x.id,
t.name,
ifnull(t.count, 0) as count
from
(SELECT 1 AS id
-- Part of the query below, you will need to generate dynamically,
-- just as you would otherwise need to generate 'in (1,2,3,4)'
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
) x
LEFT JOIN YourTable t
ON t.id = x.id
If the id does not exist in the table you're selecting from, you'll need to LEFT JOIN against a list of every id you want returned - this way, it will return the null values for ones that don't exist and the true values for those that do.
I would suggest creating a numbers table that is a single-columned table filled with numbers:
CREATE TABLE `numbers` (
id int(11) unsigned NOT NULL
);
And then inserting a large amount of numbers, starting at 1 and going up to what you think the highest id you'll ever see plus a thousand or so. Maybe go from 1 to 1000000 to be on the safe side. Regardless, you just need to make sure it's more-than-high enough to cover any possible id you'll run into.
After that, your query can look like:
SELECT n.id, a.*
FROM
`numbers` n
LEFT JOIN table t
ON t.id = n.id
WHERE n.id IN (1,2,3,4);
This solution will allow for a dynamically growing list of ids without the need for a sub-query with a list of unions; though, the other solutions provided will equally work for a small known list too (and could also be dynamically generated).

Database combine two queries into one

I have table that has 2 fields userId and ebayitemId. Following is table from database:
userId | ebayitemId
12 | 1
12 | 2
12 | 3
12 | 4
In my situation, the client makes request with ebayitemId to see what other items are listed with this user.( ebayitemId is unique ). So far I am using two query to select all items listed by the user. First query is
SELECT userId WHERE ebayitemId = '1'
This query gets me USERID FOR THAT EBAYITEMID.
The second query is
SELECT ebayitemId WHERE userId = '$userid'
This gives me ebayitemId 1,2,3 and 4.
My question: Is there a way to combine these two queries into one query to get above result since only one table is involved?
The query :
SELECT iu.ebayitemId
FROM t_items AS iu
INNER JOIN t_items AS ii ON (iu.userId=ii.userId)
WHERE (ii.ebayitemId= $item )
and if you don't want the first item to be selected :
SELECT iu.ebayitemId
FROM t_items AS iu
INNER JOIN t_items AS ii ON (iu.userId=ii.userId)
WHERE (ii.ebayitemId= $item )
AND (iu.ebayitemId<>ii.ebayitemId)
Note : an IN statement would be less optimized.
It can be done with
SELECT ebayitemId from table WHERE userId in (SELECT userId from table WHERE ebayitemId = '1')
Naively:
SELECT ebayitemId
FROM yourtable
WHERE userId IN (
SELECT userId
FROM yourtable
WHERE ebayitemId = '1'
)
Note there are other ways to skin this cat with joins etc.