sql query using two tables - sql

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)

Related

Linking tables on multiple criteria

I've got myself in a bit of a mess on something I'm doing where I'm trying to get two tables linked together based on multiple bits of info.
I want to link one table to another based on the basic rules of(in this hierarchy)
where main linking is where orderid matches between the two tables
records from table 2 where valid=Y,
from those i want the valid records which has the highest seqn1 number and then from those the one that has the highest seqn2 value
table1
orderid | date | otherinfo
223344 | 22/10/2020 | okokkokokooeodijjf
table2
orderid | seqn1 | seqn2 | valid | additonaldata
223344 | 1 | 3 | y | sdfsfsf
223344 | 2 | 1 | y | sffferfr
223344 | 2 | 2 | y | sfrfrefr -- This row
223344 | 2 | 3 | n | rfrg66rr
223344 | 2 | 4 | n | adwere
223344 | 3 | 4 | n | adwere
so would want the final record to be
orderid | date | otherinfo | seqn1 | seqn2 | valid | additonaldata
223344 | 22/10/2020 | okokkokokooeodijjf | 2 | 2 | y | sfrfrefr
I started off with the code below but I'm not sure I'm doing it right and I can't seem to get it to pay attention to the valid flag when i try to add it in.
SELECT * FROM table1
left JOIN table2
ON table1.orderid = table2.orderid
AND table2.seqn1 = (SELECT MAX(table2.seqn1) FROM table2 WHERE table1.orderid = table2.orderid)
AND table2.seqn2 = (SELECT MAX(table2.seqn2) FROM table2 WHERE table1.orderid = table2.orderid
AND table2.seqn1 = (SELECT MAX(table2.seqn1) FROM table2 WHERE table1.orderid = table2.orderid))
Could someone help me amend the code please.
Use row_number analytic function with partition by orderid and order by SEQNRs in the order you need. No need for multiple subselects. To add more selections for the single row, use CASE to map your values to numbers and order by them also.
Fiddle here.
with l as (
select *,
rank() over(partition by orderid order by seqn1 desc, seqn2 desc) as rn
from line
where valid = 'y'
)
select *
from header as h
join l
on h.orderid = l.orderid
and l.rn = 1
How about something like this:
;
with cte_table2 as
(
SELECT ordered
,MAX(seqn1) as seqn1
,MAX(seqn2) as seqn2
FROM table2
where valid = 'y'
group by ordered --check if you need to add 'valid' to the group by but I don't think so.
)
SELECT
t1.*
,t3.otherinfo
--,t3.[OtherFields]
from table1 t1
inner join cte_table2 t2 on t1.orderid = t2.orderid -- first match on id
left join table2 t3 on t3.orderid = t2.orderid and t3.seqn1 = t2.seqn1 and t3.seqn2 = t2.seqn2

How to do an outer join with full result between two tables

I have two tables:
TABLE1
id_attr
-------
1
2
3
TABLE2
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
As a result I want a table that show:
RESULT
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
10 | 3 | NULL
So I want the row with id=10 and id_attr=3 also when id_Attr=3 is missing in TABLE2 (and I know that because I have a NULL value (or something else) in the val column of RESULT.
NB: I could have others ids in table2. For example, after insert this row on table2: {11,1,A}, as RESULT I want:
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
10 | 3 | NULL
11 | 1 | A
11 | 2 | NULL
11 | 3 | NULL
So, for every id, I want always the match with all id_attr.
Your specific example only has one id, so you can use the following:
select t2.id, t2.id_attr, t2.val
from table2 t2
union all
select 10, t1.id_attr, NULL
from table1 t1
where not exists (select 1 from table2 t2 where t2.id_attr = t1.id_attr);
EDIT:
You can get all combinations of attributes and ids in the following way. Use a cross join to create all the rows you want and then a left join to bring in the data you want:
select i.id, t1.id_attr, t2.val
from (select distinct id from table2) i cross join
table1 t1 left join
table2 t2
on t2.id = i.id and t2.id_attr = t1.id_attr;
It sounds like you want to do just an outer join on id_attr instead of id.
select * from table2 t2
left outer join table1 t1 on t2.id_attr = t1.id_attr;

Write a query to fetch data from two database

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

SQL left join two tables independently

If I have these tables:
Thing
id | name
---+---------
1 | thing 1
2 | thing 2
3 | thing 3
Photos
id | thing_id | src
---+----------+---------
1 | 1 | thing-i1.jpg
2 | 1 | thing-i2.jpg
3 | 2 | thing2.jpg
Ratings
id | thing_id | rating
---+----------+---------
1 | 1 | 6
2 | 2 | 3
3 | 2 | 4
How can I join them to produce
id | name | rating | photo
---+---------+--------+--------
1 | thing 1 | 6 | NULL
1 | thing 1 | NULL | thing-i1.jpg
1 | thing 1 | NULL | thing-i2.jpg
2 | thing 2 | 3 | NULL
2 | thing 2 | 4 | NULL
2 | thing 2 | NULL | thing2.jpg
3 | thing 3 | NULL | NULL
Ie, left join on each table simultaneously, rather than left joining on one than the next?
This is the closest I can get:
SELECT Thing.*, Rating.rating, Photo.src
From Thing
Left Join Photo on Thing.id = Photo.thing_id
Left Join Rating on Thing.id = Rating.thing_id
You can get the results you want with a union, which seems the most obvious, since you return a field from either ranking or photo.
Your additional case (have none of either), is solved by making the joins left join instead of inner joins. You will get a duplicate record with NULL, NULL in ranking, photo. You can filter this out by moving the lot to a subquery and do select distinct on the main query, but the more obvious solution is to replace union all by union, which also filters out duplicates. Easier and more readable.
select
t.id,
t.name,
r.rating,
null as photo
from
Thing t
left join Rating r on r.thing_id = t.id
union
select
t.id,
t.name,
null,
p.src
from
Thing t
left join Photo p on p.thing_id = t.id
order by
id,
photo,
rating
Here's what I came up with:
SELECT
Thing.*,
rp.src,
rp.rating
FROM
Thing
LEFT JOIN (
(
SELECT
Photo.src,
Photo.thing_id AS ptid,
Rating.rating,
Rating.thing_id AS rtid
FROM
Photo
LEFT JOIN Rating
ON 1 = 0
)
UNION
(
SELECT
Photo.src,
Photo.thing_id AS ptid,
Rating.rating,
Rating.thing_id AS rtid
FROM
Rating
LEFT JOIN Photo
ON 1 = 0
)
) AS rp
ON Thing.id IN (rp.rtid, rp.ptid)
MySQL has no support for full outer joins so you have to hack around it using a UNION:
Here's the fiddle: http://sqlfiddle.com/#!2/d3d2f/13
SELECT *
FROM (
SELECT Thing.*,
Rating.rating,
NULL AS photo
FROM Thing
LEFT JOIN Rating ON Thing.id = Rating.thing_id
UNION ALL
SELECT Thing.*,
NULL,
Photo.src
FROM Thing
LEFT JOIN Photo ON Thing.id = Photo.thing_id
) s
ORDER BY id, photo, rating

SQL return max value from child for each parent row

I have 2 tables - 1 with parent records, 1 with child records. For each parent record, I'm trying to return a single child record with the MAX(SalesPriceEach).
Additionally I'd like to only return a value when there is more than 1 child record.
parent - SalesTransactions table:
+-------------------+---------+
|SalesTransaction_ID| text |
+-------------------+---------+
| 1 | Blah |
| 2 | Blah2 |
| 3 | Blah3 |
+-------------------+---------+
child - SalesTransactionLines table
+--+-------------------+---------+--------------+
|id|SalesTransaction_ID|StockCode|SalesPriceEach|
+--+-------------------+---------+--------------+
| 1| 1 | 123 | 99 |
| 2| 1 | 35 | 50 |
| 3| 2 | 15 | 75 |
+--+-------------------+---------+--------------+
desired results
+-------------------+---------+--------------+
|SalesTransaction_ID|StockCode|SalesPriceEach|
+-------------------+---------+--------------+
| 1 | 123 | 99 |
| 2 | 15 | 75 |
+-------------------+---------+--------------+
I found a very similar question here, and based my query on the answer but am not seeing the results I expect.
WITH max_feature AS (
SELECT c.StockCode,
c.SalesTransaction_ID,
MAX(c.SalesPriceEach) as feature
FROM SalesTransactionLines c
GROUP BY c.StockCode, c.SalesTransaction_ID)
SELECT p.SalesTransaction_ID,
mf.StockCode,
mf.feature
FROM SalesTransactions p
LEFT JOIN max_feature mf ON mf.SalesTransaction_ID = p.SalesTransaction_ID
The results from this query are returning multiple rows for each parent, and not even the highest value first!
select stl.SalesTransaction_ID, stl.StockCode, ss.MaxSalesPriceEach
from SalesTransactionLines stl
inner join
(
select stl2.SalesTransaction_ID, max(stl2.SalesPriceEach) MaxSalesPriceEach
from SalesTransactionLines stl2
group by stl2.SalesTransaction_ID
having count(*) > 1
) ss on (ss.SalesTransaction_ID = stl.SalesTransaction_ID and
ss.MaxSalesPriceEach = stl.SalesPriceEach)
OR, alternatively:
SELECT stl1.*
FROM SalesTransactionLines AS stl1
LEFT OUTER JOIN SalesTransactionLines AS stl2
ON (stl1.SalesTransaction_ID = stl2.SalesTransaction_ID
AND stl1.SalesPriceEach < stl2.SalesPriceEach)
WHERE stl2.SalesPriceEach IS NULL;
I know I'm a year late to this party but I always prefer using Row_Number in these situations. It solves the problem when there are two rows that meet your Max criteria and makes sure that only one row is returned:
with z as (
select
st.SalesTransaction_ID
,row=ROW_NUMBER() OVER(PARTITION BY st.SalesTransaction_ID ORDER BY stl.SalesPriceEach DESC)
,stl.StockCode
,stl.SalesPriceEach
from
SalesTransactions st
inner join SalesTransactionLines stl on stl.SalesTransaction_ID = st.SalesTransaction_ID
)
select * from z where row = 1
SELECT SalesTransactions.SalesTransaction_ID,
SalesTransactionLines.StockCode,
MAX(SalesTransactionLines.SalesPriceEach)
FROM SalesTransactions RIGHT JOIN SalesTransactionLines
ON SalesTransactions.SalesTransaction_ID = SalesTransactionLines.SalesTransaction_ID
GROUP BY SalesTransactions.SalesTransaction_ID, alesTransactionLines.StockCode;
select a.SalesTransaction_ID, a.StockCode, a.SalesPriceEach
from SalesTransacions as a
inner join (select SalesTransaction_ID, MAX(SalesPriceEach) as SalesPriceEach
from SalesTransactionLines group by SalesTransaction_ID) as b
on a.SalesTransaction_ID = b.SalesTransaction_ID
and a.SalesPriceEach = b.SalesPriceEach
subquery returns table with trans ids and their maximums so just join it with transactions table itself by those 2 values