Write a query to fetch data from two database - sql

Followings are the table name.both database have same table and column name.
field_data_field_name
| Entity_id| field_name_value|
| 1 | XYZ |
field_data_field_address
-----------------------------------
| Entity_id | field_address_value|
| 1 | abc |
field_data_field_county
----------------------------------
| Entity_id | field_county_value|
| 1 | mumbai |
field_data_field_select_area
---------------------------------------
| Entity_id | field_select_area_value|
| 1 | pension |
users
------------------------------------
| uid | mail |
| 1 | sopu.phadke080#gmail.com |
In single database on basis of Entity_id=uid we join tables and data fetch successfully.
following is query for single database.
SELECT
field_data_field_name.field_name_value,
field_data_field_address.field_address_value,
field_data_field_county.field_county_value,
field_data_field_select_area.field_select_area_value,
users.mail
FROM users
INNER JOIN field_data_field_name On field_data_field_name.entity_id= uid
INNER JOIN field_data_field_address On field_data_field_address.entity_id = uid
INNER JOIN field_data_field_county On field_data_field_county.entity_id = uid
INNER JOIN field_data_field_select_area On field_data_field_select_area.entity_id = uid
I create this query but not working.please help me.
SELECT
a.field_name_value,
b.field_address_value,
c.field_county_value,
d.field_select_area_value,
e.field_name_value,
f.field_address_value,
g.field_county_value,
h.field_select_area_value
FROM
dbeng.field_data_field_name As a,
dbeng.field_data_field_address As b,
dbeng.field_data_field_county As c,
dbeng.field_data_field_select_area As d,
inner join dbspa.field_data_field_name As e ON <field_data_field_name.field_name_value>=<field_data_field_name.field_name_value>,
inner join dbspa.field_data_field_address As f ON <field_data_field_address.field_address_value>=<field_data_field_address.field_address_value>,
inner join dbspa.field_data_field_county As g ON <field_data_field_county.field_county_value>=<field_data_field_county.field_county_value>,
inner join dbspa.field_data_field_select_area As h ON <field_data_field_select_area.field_select_area_value>=<field_data_field_select_area.field_select_area_value>
WHERE d.field_select_area_value ='Pensión Compensatoria' && h.field_select_area_value ='Pensión Compensatoria' && c.field_county_value ='Alameda' && g.field_county_value='Alameda'

The concept of storing such information in two different databases does not sound right, but if you need to get data from both, you will have to do a UNION ALL:
SELECT x.col1, x.col2
FROM
(
SELECT a.col1, b.col1
FROM db1.a
JOIN db1.b ON ( ... )
UNION ALL
SELECT a.col1, b.col1
FROM db2.a
JOIN db2.b ON ( ... )
) x
WHERE x.col1 = ...

select Col1,Col2
from DB1..Tbl1
join Tbl2 on Tbl2.Col2 = DB1..Tbl1.Col1
You can access table of another database with syntax as : DatabaseName..TableName.ColumnName

Related

How to populate a table based on a value from a different table

I have two tables of data which I can join using a left join linked on the ID in both tables. Where the course and the person are the same, I need to populate the RegNumber as the same as the RegNumber which is already there for 1 row:
How it is currently: if I join table 1 and table 2 with a left join.
Table 1
ID | Course| Person
67705 | A | 1
68521 | A | 1
85742 | A | 1
89625 | A | 1
67857 | B | 2
86694 | B | 2
88075 | B | 2
88710 | C | 3
47924 | C | 3
66981 | C | 3
12311 | B | 1
12312 | B | 1
12313 | B | 1
Table 2
ID | RegNumber
67705 | N712316
NULL | NULL
NULL | NULL
NULL | NULL
67857 | N712338
NULL | NULL
NULL | NULL
NULL | NULL
47924 | M481035
NULL | NULL
12311 | N645525
NULL | NULL
NULL | NULL
I need table 2 to look like this:
ID | RegNumber
67705 | N712316
68521 | N712316
85742 | N712316
89625 | N712316
67857 | N712338
86694 | N712338
88075 | N712338
88710 | N712338
47924 | M481035
66981 | M481035
12311 | N645525
12312 | N645525
12313 | N645525
That is, I need to insert new rows into Table 2
Can anyone help me please? This is Totally beyond my capability!
insert into table2 (ID,RegNumber)
select t1.ID,reg.regNumber
from table1 t1
cross join (select top 1 regNumber from table2 r2 join table1 r1
on r1.Id = r2.Id
and r1.Course = t1.Course
and r1.Person = t1.person
order by id) reg
where not exists (select 1 from table2 t2 where t1.ID = t2.ID)
you can improve performance a little bit by loading data into temp table first :
select t1.ID , Course,Person,regNumber
into #LoadedData
from table1 t1
join table2 t2 on t1.Id = t2.ID
insert into table2 (ID,RegNumber)
select t1.ID,reg.regNumber
from table1 t1
cross join (select top 1 regNumber from #LoadedData l
where l.Course = t1.Course
and l.Person = t1.person
order by id) reg
where not exists (select 1 from #LoadedData l where t1.ID = l.ID)
in either case having an index on (ID, Course, Person) will help with performance
Assuming:
You are missing items in table 2 that inherit data from other records in table 1.
What makes two different IDs share the same Regnumber is to have BOTH course and person number in common.
You really need to join table 1 to itself to create the mapping that associates ID 67705 with ID 68521, then you can join in table 2 to pick up the Regnumber.
Try this:
Insert into table2 (ID,RegNumber)
Select right1.ID, left2.RegNumber
From (
(table2 left2 INNER JOIN
table1 left1 On (left1.ID=left2.ID)
INNER JOIN table1 right1 On (left1.Course=right1.Course AND left1.Person=right1.Person)
) LEFT OUTER JOIN table2 right2 On (right1.ID=right2.ID)
WHERE right2.ID Is Null
The 4th table join (alias right2) is purely defensive, to handle two records in table2 having identical Person & Course in table1.
I have solved this myself.
I concatenated the person and course columns and then joined them using that new concatenated field
insert into table 2 (ID,RegNumber)
select X1.ID,X2.Regnumber
from (select concat(course,person) as X,ID from table1) X1
join (select concat(t1.course,t1.person) as X, t2.RegNumber
from table1 t1
join table2 t2 on t1.ID = t2.ID) X2
on X1.X = X2.X
where X1.ID not in (select ID from table2)

SQL Performance Inner Join

Let me ask you something I've been thinking about for a while. Imagine that you have two tables with data:
MAIN TABLE (A)
| ID | Date |
|:-----------|------------:|
| 1 | 01-01-1990|
| 2 | 01-01-1991|
| 3 | 01-01-1992|
| 4 | 01-01-2000|
| 5 | 01-01-2001|
| 6 | 01-01-2003|
SECONDARY TABLE (B)
| ID | Date | TOTAL |
|:-----------|------------:|--------:|
| 1 | 01-01-1990| 1 |
| 2 | 01-01-1991| 2 |
| 3 | 01-01-1992| 1 |
| 4 | 01-01-2000| 5 |
| 5 | 01-01-2001| 8 |
| 6 | 01-01-2003| 7 |
and you want to select only ID with date greater than 31-12-1999 and get the following columns: ID, Date and Total. For that we have many options but my question would be which of the following would be better in terms of performance:
OPTION 1
With main as(
select id,
date
from A
where date > '31-12-1999'
)
select main.id,
main.date,
B.total
from main inner join B on main.id = b.id
OPTION 1
With main as(
select id,
date
from A
where date > '31-12-1999'
),
secondary as (
select id,
total
from B
where date > '31-12-1999'
)
select main.id,
main.date,
secondary.total
from main inner join secondary on main.id = b.id
Which of both queries would be better in terms of performance? Thanks in advance!
DATE FOR BOTH TABLES MEANS THE SAME
You don't need to use CTE you can directly join two tables -
select A.id,
A.date,
B.total
from A inner join B on A.id = b.id
where A.date > '31-12-1999'
You would need to test on your data. But there is really no need for CTEs:
select a.id a.date, b.total
from a inner join
b
on a.id = b.id
where a.date > '1999-12-31' and b.date > '1999-12-31';
As for your specific question, the two queries are not the same, because the first is filtering on only one date and the second is filtering on two dates. You should run the query that implements the logic that you intend.

Trying to write an inner join to filter out some conditions

I'm currently struggling with carrying out some joins and hoping someone can shed some light on this.
I have three tables: A,B,C
Table C lists names of individuals
Table A lists the food they like to eat
Table B is the link to show what food in A a person likes from C (Our
system was built without foreign keys! I know, it's a pain!)
What I'm trying to write is a query that will return a list of values from Table C which shows the individuals that don't like a specific food...say PFC
I have the following:
select * from table_c c
inner join table_b b
on c.name = b.bValue
inner join table_a a
on b.aValue = a.number
where a.value not in('PFC')
I'm assuming the joins are working but as table A has multiple values, the two extra rows are being returned. Is it possible to not show this client if one of the joins shows a food I don't want to see?
Table A
|---------------------|------------------|
| Number | Value |
|---------------------|------------------|
| 1 | McDs |
|---------------------|------------------|
| 1 | KFC |
|---------------------|------------------|
| 1 | PFC |
|---------------------|------------------|
Table B
|---------------------|------------------|
| bValue | aValue |
|---------------------|------------------|
| John | 1 |
|---------------------|------------------|
Table C
|---------------------|
| Name |
|---------------------|
| John |
|---------------------|
I'm also using SQL Server 2013 if that makes a difference!
With NOT EXISTS:
select * from table_c c
where not exists (
select 1 from table_b b inner join table_a a
on b.aValue = a.number
where b.bValue = c.name and a.value = 'PFC'
)
One option is to aggregate by name:
SELECT
c.Name
FROM table_c c
INNER JOIN table_b b
ON c.Name = b.bValue
INNER JOIN table_a a
ON b.aValue = a.Number
GROUP BY
c.Name
HAVING
COUNT(CASE WHEN a.Value = 'PFC' THEN 1 END) = 0;
We could also try expressing this using an exists query:
SELECT
c.Name
FROM table_c c
WHERE NOT EXISTS (SELECT 1 FROM table_b b
INNER JOIN table_a a
ON b.aValue = a.Number
WHERE c.Name = b.bValue AND
a.Value = 'PFC');

SQL Server - Select first row that meets criteria

I have 2 tables that contain IDs. There will be duplicate IDs in one of the tables and I only want to return one row for each matching ID in table B. For example:
Table A
+-----------+-----------+
| objectIdA | objectIdB |
+-----------+-----------+
| 1 | A |
| 1 | B |
| 1 | D |
| 5 | F |
+-----------+-----------+
Table B
+-----------+
| objectIdA |
+-----------+
| 1 |
| 5 |
+-----------+
Would return:
+-----------+-----------+
| objectIdA | objectIdB |
+-----------+-----------+
| 1 | D |
| 5 | F |
+-----------+-----------+
I only need one entry from Table A that matches Table B. It doesn't matter which row of table A is returned.
I'm using SQL Server.
Thanks.
;WITH CTE
AS (
SELECT B.objectIdA
,A.objectIdB
,ROW_NUMBER() OVER (PARTITION BY B.objectIdA ORDER BY A.objectIdB DESC) rn
FROM TableA A
INNER JOIN TableB B ON A.objectIdA = B.objectIdA
)
SELECT C.objectIdA
,C.objectIdB
FROM CTE
WHERE rn = 1
You can do so,by using a subselect for table a to get one entry per objectIdA group
select b.*,a.[objectIdB]
from b
join
(select [objectIdA], max([objectIdB]) [objectIdB]
from a group by [objectIdA]
) a
on(b.[objectIdA] = a.[objectIdA])
Fiddle Demo
Edit deom comments to get a whole row from tablea you can use a self join for tablea
select b.*,a.*
from b
join a
on(b.[objectIdA] = a.[objectIdA])
join (select [objectIdA], max([objectIdB]) [objectIdB]
from a group by [objectIdA]) a1
on(a.[objectIdA] = a1.[objectIdA]
and
a.[objectIdB] = a1.[objectIdB])
Fiddle Demo 2
SELECT MAX(b.ID) AS ID
,MAX(Value) AS Value
,MAX(OtherCol1) AS OtherCol1
,MAX(OtherCol2) AS OtherCol2
,MAX(OtherCol3) AS OtherCol3
FROM TblA AS a
INNER JOIN TblB AS b ON a.TblBID = b.ID
GROUP BY TblBID
Table A
Table B
Table A Data
Table B Data
Query Result
You should use PARTITION OVER to achieve the results.
SELECT
t.objectIdA,
t.objectIdB
FROM (
SELECT
a.objectIdA,
a.objectIdB,
rowid = ROW_NUMBER() OVER (PARTITION BY a.objectIdA ORDER BY a.objectIdB DESC)
FROM TableA a
INNER JOIN TableB b ON (a.objectIdA = b.objectIdA)
) t
WHERE rowid <= 1
Fiddle Code: http://sqlfiddle.com/#!3/a2ccd/1

sql query using two tables

Table one:
|user_id|hotel_id|
| 1 | 4 |
| 1 | 5 |
| 2 | 6 |
| 4 | 7 |
table two:
|hotel_id|hotel_name|more_ifo|
| 4 | bla |bla |
| 5 | bla |bla |
| 6 |more bla |bla |
| 7 | bla |bla |
I want to get all the info of the hotels that a certain user have for example user one hotels 4 and 5 .. any help? I tried using join but I guess I'm not using it correctly..?
SELECT users.*, hotels.*
FROM users
INNER JOIN hotels
ON users.hotel_id = hotels.hotel_id
Note that using * in a SELECT clause is considered bad practice; I only do it here as part of an example of using joins.
If you want to search for the hotels associated with a specific user, just add a WHERE clause to that effect:
SELECT users.*, hotels.*
FROM users
INNER JOIN hotels
ON users.hotel_id = hotels.hotel_id
WHERE users.user_id = ?
t1 is alias for table one and
t2 is alias table two
select t1.user_id,t2.hotel_id,t2.hotel_name,t2.more_info
from table_one t1 INNER JOIN table_two t2
ON t1.hotel_id=t2.hotel_id
where t1.user_id=1;
You could query all hotels for a user with an exists clause:
select *
from hotels
where exists
(
select *
from users
where users.hotel_id = hotels.hotel_id
and users.user_id = #YourUserId
)
Select B.more_ifo
From table_one A, table_two B
Where A.hotel_id = B.hotel_id
This isn't work ?
After that;
Select B.more_ifo
From table_one A, table_two B
Where A.hotel_id = B.hotel_id
AND A.hotel_id IN (4, 5)