How to get records from table based on two other tables JPA - jpa

I'm trying to do something simple in JPA.
I have a table Businesses:
BusinessId name
------------ ------
1 Joe
2 bob
And table Products:
productID name
------------ ------
1 Pen
2 paper
Because they related as meny-to-many I created another table businessesHasProductID:
BusinessId productID
------------ -----------
1 1
1 2
2 2
Now I want to select BusinessId and productID form businessesHasProductID where the name of BusinessId = 'x' and the name of productID = 'y'.
I built the tables and then I created the entity classes (from wizard in netBeans). I know how to get the "Businesses" table where Businesses.name = 'x' and I know how to get "Products" table where Products.name = 'y'. but I want to combine these results and get the IDs.
I tried to do :
Query query = getEntityManager().createQuery("
SELECT b FROM businessesHasProductID WHERE b.BusinessId IN
(SELECT t0.BusinessId FROM Businesses t0 WHERE t0.BusinessId = 'x')
AND b.productID IN
(SELECT t1.productID FROM Products t1 WHERE t1.productID = 'y')
");
That's not worked. It complains that the IN contains invalid data.

If I understand correctly, you want to get all the [bId, pId] tuples that exist in the join table and for which the name of the business identified by bId is 'x' and the name of the product identified by pId is 'y'.
If so, the following query should do what you want:
select business.businessId, product.productId
from Business business
inner join business.products product
where business.name = 'x'
and product.name = 'y'

Related

PL/SQL error ORA-00904: invalid identifier using merge, select and set

I'm new to PL/SQL. I've created a table called orders which has a pk as orders_id and a products table with a pk as products_id. Both are numbers 1 through 10. In the orders table is a column called item_name, which I want to merge into the products column called item_name.
This is what I have tried:
MERGE INTO products
USING (
SELECT item_name
FROM orders)
ON (orders.order_id = products.product_id)
WHEN MATCHED THEN
UPDATE SET
products.item_name = orders.item_name
AND
MERGE INTO products
USING (
SELECT item_name
FROM orders)
ON (products.product_id=orders.order_id )
WHEN MATCHED THEN
UPDATE SET
products.item_name2 = orders.item_name
I keep getting the error "ORA-00904: "ORDERS"."ORDER_ID": invalid identifier". I've checked order_id is a NUMBER the same as the product_id. I have also created a column in products called item_name2, but that didn't work either. What does the error mean? Any help is appreciated, thank you.
Here's how.
Sample tables:
SQL> select * from orders;
ORDERS_ID ITEM_N
---------- ------
1 Name A
2 Name B
3 Name C
5 Name E
SQL> select * from products;
PRODUCTS_ID ITEM_NAME
----------- ----------
1
2
3
4
Updating products.item_name from the orders table:
SQL> merge into products p
2 using orders o
3 on (o.orders_id = p.products_id)
4 when matched then update set
5 p.item_name = o.item_name;
3 rows merged.
Result:
SQL> select * from products;
PRODUCTS_ID ITEM_NAME
----------- ----------
1 Name A
2 Name B
3 Name C
4 --> no matching IDs, so it is left empty
SQL>

PostgreSQL: Merging sets of rows which text fields are contained in other sets of rows

Given the following table, I need to merge the fields in different "id" only if they are the same type (person or dog), and always as the value of every field of an "id" is contained in the values of other "ids".
id
being
feature
values
1
person
name
John;Paul
1
person
surname
Smith
2
dog
name
Ringo
3
dog
name
Snowy
4
person
name
John
4
person
surname
5
person
name
John;Ringo
5
person
surname
Smith
In this example, the merge results should be as follows:
1 and 4 (Since 4's name is present in 1's name and 4's surname is empty)
1 and 5 cannot be merged (the name field show different values)
4 and 5 can be merged
2 and 3 (dogs) cannot be merged. They have only the field "name" and they do not share values.
2 and 3 cannot be merged with 1, 4, 5 since they have different values in "being".
id
being
feature
values
1
person
name
John;Paul
1
person
surname
Smith
2
dog
name
Ringo
3
dog
name
Snowy
5
person
name
John;Ringo
5
person
surname
Smith
I have tried this:
UPDATE table a
SET values = (SELECT array_to_string(array_agg(distinct values),';') AS values FROM table b
WHERE a.being= b.being
AND a.feature= b.feature
AND a.id<> b.id
AND a.values LIKE '%'||a.values||'%'
)
WHERE (select count (*) FROM (SELECT DISTINCT c.being, c.id from table c where a.being=c.being) as temp) >1
;
This doesn't work well because it will merge, for example, 1 and 5. Besides, it duplicates values when merging that field.
One option is to aggregate names with surnames on "id" and "being". Once you get a single string per "id", a self join may find when a full name is completely included inside another (where the "being" is same for both "id"s), then you just select the smallest fullname, candidate for deletion:
WITH cte AS (
SELECT id,
being,
STRING_AGG(values, ';') AS fullname
FROM tab
GROUP BY id,
being
)
DELETE FROM tab
WHERE id IN (SELECT t2.id
FROM cte t1
INNER JOIN cte t2
ON t1.being = t2.being
AND t1.id > t2.id
AND t1.fullname LIKE CONCAT('%',t2.fullname,'%'));
Check the demo here.

Limit for inner Join Table

I have a scenario where I am joining three tables and getting the results.
My problem is i have apply limit for joined table.
Take below example, i have three tables 1) books and 2) Customer 3)author. I need to find list of books sold today with author and customer name however i just need last nth customers not all by passing books Id
Books Customer Authors
--------------- ---------------------- -------------
Id Name AID Id BID Name Date AID Name
1 1 1 ABC 1 A1
2 2 1 CED 2 A2
3 3 2 DFG
How we can achieve this?
You are looking for LATERAL.
Sample:
SELECT B.Id, C.Name
FROM Books B,
LATERAL (SELECT * FROM Customer WHERE B.ID=C.BID ORDER BY ID DESC LIMIT N) C
WHERE B.ID = ANY(ids)
AND Date=Current_date

counting in sql in subquery in the table

DNO DNAME
----- -----------
1 Research
2 Finance
EN ENAME CITY SALARY DNO JOIN_DATE
-- ---------- ---------- ---------- ---------- ---------
E1 Ashim Kolkata 10000 1 01-JUN-02
E2 Kamal Mumbai 18000 2 02-JAN-02
E3 Tamal Chennai 7000 1 07-FEB-04
E4 Asha Kolkata 8000 2 01-MAR-07
E5 Timir Delhi 7000 1 11-JUN-05
//find all departments that have more than 3 employees.
My try
select deptt.dname
from deptt,empl
where deptt.dno=empl.dno and (select count(empl.dno) from empl group by empl.dno)>3;
here is the solution
select deptt.dname
from deptt,empl
where deptt.dno=empl.dno
group by deptt.dname having count(1)>3;
select
*
from departments d
inner join (
select dno from employees group by dno having count(*) > 3
) e on d.dno = e.dno
There are many approaches to this problem but almost all will use GROUP BY and the HAVING clause. That clause allows you to filter results of aggregate functions. Here it is used to choose only those records where the count is greater than 3.
In the query structure used above the group by is handled on the employee table only, then the result (which is known as a derived table) is joined by an INNER JOIN to the departments table. This inner join only allows matching records so this has the effect of filtering the departments table to only those which have a count() of greater than 3.
An advantage of this query structure is fewer records are joined, and also that all columns of the departments table are available for reporting. Disadvantage of this structure is the the count() of employees per department isn't visible.

How to fetch two column value in one colume based on boolean field

I am working with SQL Server 2005.
I am having 3 table
Product
PId | PName
Service
SId | SName
Bill
BId | TypeId | IsService
TypeId is PId or SId. based on IsService Field.
If IsService is 1 then TypeId is SId and If IsService is 0 then TypeId is PId
I want to fetch PName and SName with Bill so how can I?
I am thinking of to Write stored Procedure for this..
and Adding Dynamic Column to Stored Procudure that column contain Either SName or PName as per IsService.
But don't know how to write this also?
Maybe something like this:
SELECT
Bill.*,
CASE
WHEN Bill.IsService=1
THEN Service.SName
ELSE Product.PName
END AS Name
FROM
Bill
LEFT JOIN Service
ON Bill.TypeId=Service.SId
LEFT JOIN Product
ON Product.TypeId=Bill.BId
SELECT
t.BId,
tt.Name
FROM Bill t
Outer Apply
(
SELECT PName AS name FROM Product WHERE 0 = t.IsService AND PId = t.TypeId
UNION ALL
SELECT SName AS name FROM Servicess WHERE 1 = t.IsService AND SId = t.TypeId
) tt