MySQL List data where they share the same name/id - java

Print each movie name, then print a list of theater IDs and screens where it is playing/has played. For example, for the movie with ID=10, the output will look like
Frankenstein: (7, 17); (314, 73); (4345, 1)
This must be done for all movies. If a movie does not have any showings, you may show it with the list empty, or simply not show it at all (either will be considered correct for this problem).
Im having a hard time figuring out how to select the name then list out (TheaterID, Screen#)
Here are what the tables look like
I started todo the following from another example I found but doesn't seem like it would work.
SELECT movies.MOVIENAME, playing.THEATERID, playingSCREEN.#, count(*) as seqnum
FROM movies, playing
LEFT OUTER JOIN
movies.MOVIEID = playing.MOVIEID
ON p.plantid = pprev.plantid AND p.name >= pprev.name
GROUP BY p.plantid, p.name
Playing when MOVIEID is set to 93
Movies when MOVIEID is set to 93

You can use the following. Also I think it's a bad practice to have # in your column name.
SELECT aa.MOVIEID, aa.MOVIENAME, bb.SCREEN, bb.THEATERID
FROM movie AS aa
LEFT JOIN playing AS bb
ON aa.MOVIDEID = bb.MOVIEID
ORDER BY aa.MOVIEID;

Related

Simple SQL query on highest ID

I unsuccessfully attempted to leverage Java's DerivedQueries but cannot accomplish the required result so I have to manually write a SELECT Statement.
I want to display one single record in my UI. This should be the most recently generated record (which means it has the highest ID Number) associated with a category that we call "ASMS". In other words, look through all the rows that have ASMS#123, find the one that has the highest ID and then return the contents of one column cell.
ASMS: Entries are classified by 11 specific ASMS numbers.
ID: AutoGenerated
PPRECORD: New entries being inserted each day
I hope the image makes more sense.
//RETURN ONLY THE LATEST RECORD
//https://besterdev-api.apps.pcfepg3mi.gm.com/api/v1/pprecords/latest/{asmsnumber}
#RequestMapping("/pprecords/latest/{asmsNumber}")
public List<Optional<PriorityProgressEntity>> getLatestRecord(#PathVariable(value = "asmsNumber") String asmsNumber) {
List<Optional<PriorityProgressEntity>> asms_number = priorityprogressrepo.findFirst1ByAsmsNumber(asmsNumber);
return asms_number;}
The ReactJS FE makes an AXIOS.get and I can retrieve all the records associated with the ASMS, but I do not have the skill to display only JSON object that has the highest ID value. I'm happy to do this in the FE also.
I tried Derived Queries. .findFirst1ByAsmsNumber(asmsNumber) does not consider the highest ID number.
Try this:
SELECT pprecord FROM YourTable WHERE id =
(SELECT MAX(id) FROM YourTable WHERE asms = '188660')
Explanation:
First line select pprecord, second line select the id
I'll improve the answer if any additional question. Upvotes and acceptions are appreciated~

Filtering out duplicate entires for older rows

There's 2 tables;
OITM that references an Item's information and stock amounts
OINM that references all changes to all Item's stock amounts.
Currently, I've already built a SQL that lets me SELECT new changes to Item stock by joining the tables, but I've run into the issue that sometimes there's duplicate entries, when OINM had two changes to the same Item.
This is the SQL i currently have is as follows:
SELECT T0.\"ItemCode\", T0.\"WhsCode\", T0.\"OnHand\", T0.\"IsCommited\", T0.\"OnOrder\", T1.\"DocDate\", T1.\"DocTime\"
FROM KA_DEV6.OITW T0,KA_DEV6.OINM T1
WHERE T0.\"WhsCode\" = '01' AND T0.\"ItemCode\" = T1.\"ItemCode\"
AND (T1.\"DocDate\" > '2019-10-20' OR (T1.\"DocDate\" = '2019-10-20' AND T1.\"DocTime\" >= '1025'))
This outputs the following result:
|ItemCode:CC01.NB.C.LF.F.LI.V.0813.GRCE|WhsCode:01|OnHand:8.000000|IsCommited:4.000000|OnOrder:0.000000|DocDate:2019-10-22 00:00:00.000000000|DocTime:1024
|ItemCode:JO.C.LF.U.LI.V.0004. 22.NG|WhsCode:01|OnHand:1.000000|IsCommited:0.000000|OnOrder:0.000000|DocDate:2019-10-21 00:00:00.000000000|DocTime:1223
|ItemCode:JO.I.FT.M.AB.C.0106. L.NG|WhsCode:01|OnHand:32.000000|IsCommited:0.000000|OnOrder:0.000000|DocDate:2019-10-21 00:00:00.000000000|DocTime:1401
|ItemCode:JO.I.FT.M.AB.C.0106. L.NG|WhsCode:01|OnHand:38.000000|IsCommited:0.000000|OnOrder:0.000000|DocDate:2019-10-21 00:00:00.000000000|DocTime:1402
The issue is that there are entries that have the same ItemCode, and I only need the most recent change. (Thus, I'd need to filter out the 3rd result, only returning the most recent which is 4th.)
How could I go about this? Because my ordering is by 2 fields (DocDate and DocTime), and then filter out the duplicates.
Ordering is already something i can do and works which is adding
ORDER BY T1.\"DocDate\", T1.\"DocTime\" ASC
But how do i filter out duplicates?
Expected output would be:
|ItemCode:CC01.NB.C.LF.F.LI.V.0813.GRCE|WhsCode:01|OnHand:8.000000|IsCommited:4.000000|OnOrder:0.000000|DocDate:2019-10-22 00:00:00.000000000|DocTime:1024
|ItemCode:JO.C.LF.U.LI.V.0004. 22.NG|WhsCode:01|OnHand:1.000000|IsCommited:0.000000|OnOrder:0.000000|DocDate:2019-10-21 00:00:00.000000000|DocTime:1223
|ItemCode:JO.I.FT.M.AB.C.0106. L.NG|WhsCode:01|OnHand:38.000000|IsCommited:0.000000|OnOrder:0.000000|DocDate:2019-10-21 00:00:00.000000000|DocTime:1402
Regards
EDIT: For anyone reading in the future, and checking out the answer, do note that for my case, the actual ordering of the information didnt matter, since i dont care about it being the newst change, only filtering out duplicates. For the actual most recent table, you need to change the Order By clause from the sub query to ORDER BY T1.\"DocDate\",T1.\"DocTime\" DESC and optionally, at the end of the entire query again to order the results.
You can use the ROW_NUMBER windowing function to this like this:
SELECT *
FROM (
SELECT T0.\"ItemCode\", T0.\"WhsCode\", T0.\"OnHand\", T0.\"IsCommited\", T0.\"OnOrder\", T1.\"DocDate\", T1.\"DocTime\",
ROW_NUMBER() OVER (PARTITION BY T0.\"ItemCode\" ORDER BY T1.\"DocTime\" DESC) AS RN
FROM KA_DEV6.OITW T0
JOIN KA_DEV6.OINM T1 ON T0.\"WhsCode\" = '01' AND T0.\"ItemCode\" = T1.\"ItemCode\"
WHERE T1.\"DocDate\" > '2019-10-20' OR (T1.\"DocDate\" = '2019-10-20' AND T1.\"DocTime\" >= '1025')
) X
WHERE RN = 1
Note -- I also used standard join syntax not the 20+ year old syntax you were using.

How to make a query with the operator MIN() and something filtered inside in JPQL?

I have a class Sponsor who has a Collection<Campaign>. And each Campaign has just one Sponsor.
For example, if I have it:
SELECT MIN(s.campaigns.size) FROM Sponsor s;
It returns the campaigns.size of the Sponsor who has the minimum campaigns.
But if I want to COUNT the campaigns 'c' whose c.attribute=null per Sponsor, and then return the minimum of it?
A visual example of what I want to get could be:
select min(select count(c) from Campaign c where c.sponsor.id=s.id and c.finishMoment is null) from Sponsor s;
The thing is that it's not possible to include a SELECT into the function MIN.
Hard to say what your looking for. Here's something along those lines.
** Sorry, not a jpql guy, but apparently you can take the first result, so you could do the select and order it by the count and just take the first result
Sorry, your going to have to work out the join, but you get the idea.
SELECT Campaign.id,COUNT(Campaign.id)
FROM Campaign
JOIN Sponsor on (Sponsor.id = Campaign.id)
WHERE finishMoment is null
GROUP BY Campaign.id
ORDER BY COUNT(Campaign.id)
**This is SQL
SELECT MIN(sponsorCount)
FROM (SELECT Campaign.id,COUNT(*) sponsorCount
FROM Campaign
JOIN Sponsor on (Sponsor.id = Campaign.id)
WHERE finishMoment is null
GROUP BY Campaign.id);

Object modification inconsistency on Play framework 2.2.X

Here's the deal:
public static List<Survey> getFilteredSurveys(Municipality municipality, Company company) {
String sql = "SELECT DISTINCT id FROM survey INNER JOIN " +
"(SELECT SURVEY_ID FROM publicity INNER JOIN brand "+
"ON publicity.brand_id=brand.id WHERE brand.company_id="+company.getId()+") "+
"ON survey_id=survey.id WHERE survey.municipality_id="+municipality.getId();
RawSql rawSql = RawSqlBuilder.parse(sql).create();
List<Survey> surveys = Ebean.find(Survey.class).setRawSql(rawSql).findList();
for (Survey survey : surveys) {
List<Publicity> publicities = new ArrayList<>();
for (Publicity publicity : survey.publicities) {
if(publicity.getBrand().getCompany() == company){
publicities.add(publicity);
}
}
survey.setPublicities(publicities);
}
return surveys;
}
This app is meant for measuring Publicities in a given place,
So people upload a 'Survey' of a place containing all the 'Publicity' that place has.
That function is supposed to return a List,
Each Survey has a List,
And each Publicity has a Brand, which is associated to a Company (ex. Coke -> Coca Cola Co.)
What I'm trying to do is this:
Given a Company, show all the surveys that contain a 'Coca Cola Co.' publicity, but showing only the publicities that belong to 'Coca Cola Co.'
I have a 'Surveys' controller which receives a form with a Municipality and a Company, calls this method, and it renders a view with its result.
This is part of the view template:
#(surveys: java.util.List[Survey])
#for(survey <- surveys){
#for(publicity <- survey.getPublicities){
<tr>
<td>#publicity.getBrand.getName</td>
<td>#publicity.getType.getName</td>
<td>#publicity.getSquareMeters</td>
</tr>
}
}
Problem: even though I removed some publicities from each Survey, all the publicities show up in the view. Why is this happening?
I know I'm not persisting the changes, and I don't want to, I just want to temporarily obfuscate the data so the user only sees the publicities that belong to a given company.
Why isn't this view using the surveys as they are given to it, modified?
Actually I'll put this in an answer ...
You should look at the SQL executed in the log (because I suspect you are getting N+1) here and you could fairly easily avoid that.
You should probably look to change your raw sql to include the publicities columns in the select clause (name, type, squareMeters) to avoid the extra queries.
Alternatively you could add fetch("publicities") to the query (so that they are fetched eagerly via a query join 100 at a time).
Also refer to:
https://github.com/ebean-orm/avaje-ebeanorm/issues/223
... RawSql that includes a OneToMany not working
https://github.com/ebean-orm/avaje-ebeanorm/issues/224
... Enhancement adding RawSqlBuilder.tableAliasMapping()
Ideally you'd be able to use 4.5.2 and take advantage of that fix and that enhancement.
So, I found a fix,
My fix was:
for (Survey survey : surveys) {
survey.getAddress(); //This line fixes the issue
List<Publicity> publicities = new ArrayList<>();
for (Publicity publicity : survey.publicities) {
if(publicity.getBrand().getCompany() != null){
if(publicity.getBrand().getCompany().getId().equals(company.getId())){
publicities.add(publicity);
}
}
}
survey.setPublicities(publicities);
}
My guess is that the problem resides in the way ebean lazily instantiates objects, despite setting Publicities to FetchType.EAGER, and the fact that the output from this function was the expected one, also inspecting surveys in the controller seemed to be ok, and also a #println(surveys) in the view showed only the publicities corresponding to the company I had selected.

Restricting hibernate's eager fetch beyond DAO

I have my entities as ProductType,Product and ProductInventory.
I have a join query to fetch list of inventory for a specific date range which joins Product and ProductInventory. I've got list of object arrays which I have casted and set it ready.
Now from DAO I return the list of products.
In my layer above, if I execute product.getProductInventory() it is actually firing a query again getting all the inventory and not those inventory as got by the join.
final StringBuilder queryString = new StringBuilder(
"from Product As rsProduct left outer join rsProduct.inventoryList "
+ "as inventory where rsProduct.efDate <= :travelEndDate AND rsProduct.expDate >= :travelStartDate AND rsProduct.locatiion = :LOCN AND rsProduct.id in (:productsIdList) and inventory.bookDate between :startDate and :endDate");
Ex. Say travel start date is 20th Jan and travel end date is 21 Jan. I get only two records here which is perfect.
But after i return to other layer, if i say product.getInventory() it fetches all inventory irrespective of dates.
Can someone address this problem?
You should define a filter and enable it before accessing the collection.

Categories

Resources