in our chat application, the following is the case, there is person 'A' who have chat with person 'B' in two cases,1) one-to-one chat and 2) group chat. so in the database records are as follows,
Table : core
id name
1 A
2 B
3 C
Table : Master
id core_id
1 1
2 2
Table : recepient
id core_id master_id
1 1 1
2 2 1
3 1 2
4 2 2
5 3 2
so in the recepient table, we have 2 entries for Person 'A'. Now the problem is, i want the master_id = 1 form recepient table, in which person 'A' and 'B' are communicated. But there are two entries in recepient table for this. so how to get that id?
It's unclear what you are asking and your table names do not assist in making this any clearer. However, I suspect you are selecting records from the recipient table based only on the master_id and need to join with the other tables so that you can also include the name in the query.
So with this in mind, try the following (caveat: I haven't tested this, and I work with Oracle not mysql) but:
select *
from core c, master m, recipient r
where c.id = m.core_id
and c.id = r.core_id
and m.id = r.master_id
and c.name = 'A'
And before anyone complains that this sql does not follow the latest ANSI standard, it's the way I do it and it works for me!
Related
I have two oracle table:users and logs,as follow,
users:
---------
id number,
name varchar2(50)
logs:
-----
user_id number,
visit_date date
I need to find out the first 10 users who never appears in the logs table (means they never visit the page),I can write a sql:
select *
from users u
where not exists (
select 1 from logs o
where o.user_id = u.id)
and rownum<=10
But now the problem is these two table are not in the same schema,they could not be accessed for each other,so I can not join them.
Because there are two microservices,one microservice should query its own schema
If I fetch 10 records from users,maybe they all never visit the page,I need to fetch 10 more,then after that still 5 users did not visit that page,I need to fetch 5 more,and so on.So I am not sure how many record I should fetch at the first time.Is it a good idea to do so?And how to write the code?
If I fetch all the record of the 2 tables,then do join using Java code,I'm worried about the amount of data being too large.Or should I just make these two tables accessible to each other?
So,how to do paging with 2 table but not join them?
But now the problem is these two table are not in the same schema,they could not be accessed for each other,so I can not join them.
Create a user that can see both schemas and log in to that user and access the tables using schema_name.table_name:
SELECT *
FROM schema1.users u
WHERE NOT EXISTS (
SELECT 1
FROM schema2.logs l
WHERE l.user_id = u.id
)
ORDER BY u.something
FETCH FIRST 10 ROWS ONLY
or
SELECT *
FROM (
SELECT *
FROM schema1.users u
WHERE NOT EXISTS (
SELECT 1
FROM schema2.logs l
WHERE l.user_id = u.id
)
ORDER BY u.something
)
WHERE ROWNUM <= 10
Alternatively, create a third schema and GRANT the SELECT privilege on the USERS and LOGS tables in the first two schemas and then create a view in that third schema and a new micro-service and use that.
I have a use case, where I have to merge data from 2 Tables (which are in different data sources).
Consider that each table has employee data (First name, last name, phoneNumber). For each employee, I will have to merge the phoneNumber data from both the Tables and other data will remain the same as in Table 1
If employee data is present in both Table 1 and Table 2, phoneNumber data will be merged as a comma separated values and other data will be sourced from Table 1
If employee is present only in Table 1, then entire data will be sourced from Table 1
If employee is present only in Table 2, then entire data will be sourced from Table 2
These Tables has about 40 lack rows of data each. Close to 5GB.
What is the best approach to do this in Java? My concern is if I pull the data from these 2 tables into Java cache, i will still have to loop thought the entire table 2 to see if an employee is present there as well.
Or will a python script be better?
Table 1
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
12345
EM02
Dave
Joe
34567
Table 2:
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
89000
EM03
Gabe
Mai
45678
Table 3 (After merging the phone numbers):
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
12345,89000
EM02
Dave
Joe
34567
EM03
Gabe
Mai
45678
You can easily do this as a SQL query.
Basically, you want a full join, but -- alas -- MySQL doesn't support that.
So, one method is:
select t1.EmployeeID, t1.FirstName, t1.LastName
concat_ws(',', t1.PhoneNumber, t2.PhoneNumber) as PhoneNumber
from table1 t1 left join
table2 t2
on t1.EmployeeID = t2.EmployeeID
union all
select t2.EmployeeID, t2.FirstName, t2.LastName, t2.PhoneNumber
from table2 t2
table1 t1 left join
on t1.EmployeeID = t1.EmployeeID
where t1.EmployeeID is null;
That is, get all the rows for the employees in table1. Then add in the additional rows from table2. For the first part, concat_ws() is convenient for combining the phone numbers.
I have to perform an update on a USERPRODUCTS table
PRODUCTID USERNAME PRODUCTCOUNTRY
1 A US
2 A UK
3 B US
4 B CA
5 B US
6 C IR
7 F IR
8 A IR
I have another table PERSONCOUNTRY where I know which person can have which country product license only e.g.
PERSON COUNTRYFORPRODUCTLICENSE
A UK
B US
C IR
Now what I want to do is to write a single query to update the table USERPRODUCTS and SET person A to person B such that the query should update only if B has COUNTRYFORPRODUCTLICENSE for ALL rows in USERPRODUCTS for person A otherwise should not update ANY row.
e.g. Person A has PRODUCTCOUNTRY UK, US and IR from above table but B has COUNTRYFORPRODUCTLICENSE only US. So, update query should update row 1 (because B has license for country US) but when it reaches row 2, it should ALL roll back, even the first row it updated.
I know this cannot be handled through single update
UPDATE USERPRODUCTS userproducts
SET USERNAME = 'B'
WHERE USERNAME = 'A'
AND EXISTS (SELECT * FROM PERSONCOUNTRY personcountry where USERPRODUCTS.PRODUCTCOUNTRY IN (US))
This query will update only where A has US in PRODUCTCOUNTRY but will not roll back.
What is the fastest way to do it ? I wanted to do it in a single update query but cannot. Can we use CURSOR to do it ? but I have to do it in Hibernate code
I still think you can solve this with a not exists. From your comments I get the feeling you're thinking row based, but sql works based on sets. When you execute an update statement it doesn't update a row and move to the next, it updates all rows that fit the where clause.
So something along these lines:
UPDATE USERPRODUCTS
SET USERNAME = 'B'
WHERE USERNAME = 'A'
AND EXISTS (
SELECT NULL
FROM PERSONCOUNTRY PC
WHERE PC.COUNTRYFORPRODUCTLICENSE IN ('US')
AND PC.PERSON = USERPRODUCTS.USERNAME
)
AND NOT EXISTS (
SELECT NULL
FROM PERSONCOUNTRY PC
WHERE PC.COUNTRYFORPRODUCTLICENSE NOT IN ('US')
AND PC.PERSON = USERPRODUCTS.USERNAME
)
I am using Hibernate 3.6
User is an entity class
Contact is an entity class
User has a Set<Contact>
The relationship is uni-directional and mapped as one-to-many.
I have tried out the following lazy loading and fetch combinations. Here is a list of my understanding and actual results
with session.get(User.class, <some userId>) or session.load(User.class, <some userId>)
lazy fetch result
* true join ignores lazy loading
* 1 select for retrieving the User and his contacts with a left outer join
* select 1 select for a User record
* 1 select for all contacts of the user
* subselect 1 select for a User record
* 1 select for all contacts of the user
* false join 1 select for retrieving the User and his contacts with a left outer join
* select 1 select for a User record
* 1 select for all contacts of the user
* subselect 1 select for a User record
* 1 select for all contacts of the user
with session.createQuery(from User)
lazy fetch result
* true join 1 select for all User records
* 1 select for each User record to retrieve their contacts
* respect lazy loading
* probable n + 1
* select 1 select for all User records
* 1 select for each User record to retrieve their contacts
* probable n + 1
* subselect 1 select for all User records
* 1 sub-select to retrieve all contact records in one go
* false join 1 select for all User records
* 1 select for each User record to retrieve their contacts
* probable n + 1
* select 1 select for all User records
* 1 select for each User record to retrieve their contacts
* probable n + 1
* subselect 1 select for all User records
* 1 sub-select to retrieve all contact records in one go
Here are a few questions I have:
Is my understanding correct ?
With session.get() when lazy=true, fetch=subselect why does not Hibernate execute a subselect ? I guess this is because it is absolutely un-necessary. Am I correct ?
With session.get() when lazy=false, fetch=subselect why does not Hibernate execute a subselect ? It should execute one here but it does not. I wonder why ?
With session.createQuery() when lazy=true, fetch=join why does Hibernate lazy load ? It did not do this earlier with session.get()
With session.createQuery() when lazy=false, fetch=join why does not Hibernate use a join ?
Thanks in advance
Ok people, after much digging this is what I can conclude. Just wanted to share my spoils with you all. If anyone feels they can add more to this, you are most welcome. Let me start with a sample data set.
The user table
--------------------------------------------------
USER_ID USERNAME
--------------------------------------------------
1 User One
2 User Two
3 User Three
The contact table
-------------------------------------------------------------------------------------------------------------------
CONTACTID TITLE FIRSTNAME LASTNAME CITY COUNTRY EMAIL USER_ID
-------------------------------------------------------------------------------------------------------------------
1 Mr. Clark Kent New York United States man-of-steel#anywhere.earth 1
2 Mr. Hank Ketcham Manhattan United States dennis-mitchell#somewhere.us 2
3 Mr. Tony Stark Malibu United States iron-man#anywhere.earth 2
4 Mr. Bruce Wayne Gotham United States dark-knight#gotham.us 2
Q2. With session.get() when lazy=true, fetch=subselect why does not Hibernate execute a subselect ? I guess this is because it is absolutely un-necessary. Am I correct ?
A2. Yes a subselect is absolutely un-necessary here. Here is what the subselect might look like
SELECT
u.USER_ID AS USER1_1_,
u.USERNAME AS USERNAME1_,
c.USER_ID AS USER15_1_1_,
c.CONTACTID AS CONTACTID1_,
c.CONTACTID AS CONTACTID0_0_,
c.TITLE AS TITLE0_0_,
c.FIRSTNAME AS FIRSTNAME0_0_,
c.LASTNAME AS LASTNAME0_0_,
c.CITY AS CITY0_0_,
c.COUNTRY AS COUNTRY0_0_,
c.EMAIL AS EMAIL0_0_,
FROM
user u,contact c
WHERE
u.USER_ID = 2
AND
c.USER_ID IN
(
SELECT USER_ID FROM user WHERE USER_ID = u.USER_ID
)
I do not see any benefit of executing a sub-select here over the current strategy of simply executing a seperate select for contact records. Infact, a subselect might be an un-necessary performance drain.
Q3. With session.get() when lazy=false, fetch=subselect why does not Hibernate execute a subselect ? It should execute one here but it does not. I wonder why ?
A3. Ok. Again here is what the sub-select might look like (exactly similar to the one above with some other id)
SELECT
u.USER_ID AS USER1_1_,
u.USERNAME AS USERNAME1_,
c.USER_ID AS USER15_1_1_,
c.CONTACTID AS CONTACTID1_,
c.CONTACTID AS CONTACTID0_0_,
c.TITLE AS TITLE0_0_,
c.FIRSTNAME AS FIRSTNAME0_0_,
c.LASTNAME AS LASTNAME0_0_,
c.CITY AS CITY0_0_,
c.COUNTRY AS COUNTRY0_0_,
c.EMAIL AS EMAIL0_0_,
FROM
user u,contact c
WHERE
u.USER_ID = 3
AND
c.USER_ID IN
(
SELECT USER_ID FROM user WHERE USER_ID = u.USER_ID
)
As you can see this will not yield any records since USER_ID=3 does not have any contact records. That defeats the whole purpose of doing session.get() for a User record wherein get() will return null inspite of having a valid User record in the table. So again, a seperate select for contact records is the only way out.
Q4. With session.createQuery() when lazy=true, fetch=join why does Hibernate lazy load ? It did not do this earlier with session.get()
Q5. With session.createQuery() when lazy=false, fetch=join why does not Hibernate use a join ?
Ans. My current understanding says that this maybe simply because Hibernate does not want to end up firing a join which selects a huge data set (comprising all User records and their Contact records) and loading a huge collection in-memory.
Ok so basically I have my database table. The first column is the id. The second is a pkg_id. The 3rd is not important and the 4th is the previous id that the pkg_id was located at. I need to pull the last 3 pkg_id's from the table. So basically I need to pull the last 3 17879 pkg_id's and the last 3 3075. So in this example I need to pull id 9 , 7 , 6 for 17879 and id 8, 5, 3 for 3075.
I can't get my head around it. I do have access to the previous id that it was. So you see that for id 9 it says that 17879 was last in id 7. That id 8 was last in id 5.
If anybody could help me write a query that would be great. I'm also using Java for database access so it doesn't have to be just in mysql. Thanks so much.
SELECT m.*
FROM (
SELECT pkg_id,
COALESCE(
(
SELECT id
FROM mytable mi
WHERE mi.pkg_id = md.pkg_id
ORDER BY
id DESC
LIMIT 2, 1
), 0) AS mid
FROM (
SELECT DISTINCT pkg_id
FROM mytable
) md
) q
JOIN mytable m
ON m.pkg_id <= q.pkg_id
AND m.pkg_id >= q.pkg_id
AND m.id >= q.mid
Create an index on mytable (pkg_id, id) for this to work fast.
Note this condition: m.pkg_id <= q.pkg_id AND m.pkg_id >= q.pkg_id instead of mere m.pkg_id = q.pkg_id. This is required for the index to be used efficiently.