COUNT GROUP BY

Questions and answers on designing your Servoy solutions, database modelling and other 'how do I do this' that don't fit in any of the other categories

Re: COUNT GROUP BY

Postby rafig » Tue Nov 01, 2016 1:00 pm

Just a quick 'heads up' to make sure there are 'spaces' in queries that are split over multiple lines, so maybe add an extra space before each '\', as I had a query that worked in a SQL query tool, but not in Servoy until I made sure there were spaces in all the right places ;-)
Servoy Certified Developer
Image
rafig
 
Posts: 707
Joined: Mon Dec 22, 2003 12:58 pm
Location: Watford, UK

Re: COUNT GROUP BY

Postby martijn » Tue Nov 01, 2016 3:28 pm

:D Solved
working code:

var var_sql = "UPDATE tbl_offers SET tbl_offer_goods_count = ( \
SELECT AMOUNTGOODS \
FROM ( \
SELECT COUNT(TEMP.offer) AS AMOUNTGOODS \
, TEMP.offer AS OFFERID \
FROM ( \
SELECT DISTINCT ON (tbl_offer_cargo.tbl_offer_cargo_good_id) \
tbl_offer_cargo.tbl_offer_cargo_offerid as offer \
FROM public.tbl_offer_cargo, public.tbl_offers \
WHERE tbl_offers.tbl_offer_id = tbl_offer_cargo.tbl_offer_cargo_offerid \
) TEMP \
WHERE TEMP.offer = " + tbl_offer_cargo_offerid +
"GROUP BY offer \
) TEMP2 \
)WHERE tbl_offers.tbl_offer_id = " + tbl_offer_cargo_offerid;
plugins.rawSQL.executeSQL("transport_db","tbl_offers",var_sql)
databaseManager.refreshRecordFromDatabase(forms.frm_offers.foundset,-1)

Thank you all for helping
martijn
 
Posts: 18
Joined: Mon Jun 27, 2016 10:06 am

Re: COUNT GROUP BY

Postby mboegem » Wed Nov 02, 2016 1:28 am

Two recommended improvements to your implementation:
1) pass the id as parameter to the query, rather than concatenate.
This will make PG see each or these queries as 'similar' but with different params, rather than numerous unique queries.
From a security point of view, using params will prevent sql injection.

2) To make your solution work in a multi user environment, you should broadcast the change rather than refreshing the record from database.
Refreshing the record from database will only reflect to the current user, where a broadcast will trigger all clients to update the foundset (and thus the record).

Taking your solution, this would be the improved version:
Code: Select all
var var_sql = "UPDATE tbl_offers SET tbl_offer_goods_count = ( \
SELECT AMOUNTGOODS \
FROM ( \
SELECT COUNT(TEMP.offer) AS AMOUNTGOODS \
, TEMP.offer AS OFFERID \
FROM ( \
SELECT DISTINCT ON (tbl_offer_cargo.tbl_offer_cargo_good_id) \
tbl_offer_cargo.tbl_offer_cargo_offerid as offer \
FROM public.tbl_offer_cargo, public.tbl_offers \
WHERE tbl_offers.tbl_offer_id = tbl_offer_cargo.tbl_offer_cargo_offerid \
) TEMP \
WHERE TEMP.offer = ? \
GROUP BY offer \
) TEMP2 \
) WHERE tbl_offers.tbl_offer_id = ?";
var var_params = [tbl_offer_cargo_offerid, tbl_offer_cargo_offerid];
var var_result = plugins.rawSQL.executeSQL("transport_db","tbl_offers",var_sql, var_params);
if(var_result) {
   plugins.rawSQL.flushAllClientsCache("transport_db","tbl_offers");
}
Marc Boegem
Solutiative / JBS Group, Partner
Servoy Specialist
• Servoy Certified Developer
• Servoy Valued Professional
• Freelance Developer

Image
User avatar
mboegem
 
Posts: 1750
Joined: Sun Oct 14, 2007 1:34 pm
Location: Amsterdam

Re: COUNT GROUP BY

Postby martijn » Thu Nov 03, 2016 11:33 am

great tip, but for the
1) pass the id as parameter to the query, rather than concatenate.
This will make PG see each or these queries as 'similar' but with different params, rather than numerous unique queries.
From a security point of view, using params will prevent sql injection.


params does not seem to be expected, because I get a false result with these changes
martijn
 
Posts: 18
Joined: Mon Jun 27, 2016 10:06 am

Re: COUNT GROUP BY

Postby mboegem » Thu Nov 03, 2016 10:37 pm

martijn wrote:I get a false result with these changes


Did you replace your query with my example?
The query can not work using the question marks and no params.

Something else that came to mind:
It seems to me that you're executing this query on the form which has the 'tbl_offers' record active that you need to update with this count.
In that case, from a performance point of view, it would be easier/better to query the count using databaseManager.getDatasetByQuery.
Then set the result into the tbl_offer_goods_count column, and call databaseManager.saveData();

This will automatically trigger the databroadcast that you need in a multi-user environment, but a less 'expensive' operation than 'plugins.rawSQL.flushAllClientsCache()'

This would look like this:
Code: Select all
var var_sql = "SELECT AMOUNTGOODS \
FROM ( \
SELECT COUNT(TEMP.offer) AS AMOUNTGOODS \
, TEMP.offer AS OFFERID \
FROM ( \
SELECT DISTINCT ON (tbl_offer_cargo.tbl_offer_cargo_good_id) \
tbl_offer_cargo.tbl_offer_cargo_offerid as offer \
FROM public.tbl_offer_cargo, public.tbl_offers \
WHERE tbl_offers.tbl_offer_id = tbl_offer_cargo.tbl_offer_cargo_offerid \
) TEMP \
WHERE TEMP.offer = ? \
GROUP BY offer";
var var_params = [tbl_offer_cargo_offerid];
var var_result = databaseManager.getDataSetByQuery("transport_db",var_sql, var_params,-1);
foundset.tbl_offer_goods_count = var_result.getValue(1,1);
databaseManager.saveData();
Marc Boegem
Solutiative / JBS Group, Partner
Servoy Specialist
• Servoy Certified Developer
• Servoy Valued Professional
• Freelance Developer

Image
User avatar
mboegem
 
Posts: 1750
Joined: Sun Oct 14, 2007 1:34 pm
Location: Amsterdam

Previous

Return to Programming with Servoy

Who is online

Users browsing this forum: No registered users and 12 guests