Join Tables with sum in sql query - mysql

It is showing Sum(with table name) is not valid. Kindly help:
Modws.DisplayDataGrid(dgvClosingBalance,
"Select
Invoice.Customer, Invoice.Sum(Total),
RptTempTable.Sum(INVOICETOTAL), RptTempTable.Sum(CNTOTAL),
RptTempTable.Sum(DEBITTOTAL), RptTempTable.Sum(RECEIPTTOTAL)
From Invoice
inner join RptTempTable on Invoice.Customer = RptTempTable.Customer")

RptTempTable.Sum(INVOICETOTAL) should be Sum(RptTempTable.INVOICETOTAL)
The same goes for the other calls to sum()
The table prefix belongs to the column name not the function call.
MySQL will accept this invalid SQL and will return "inderminate" (aka "random") values instead.
To understand the implications of MySQL's "loose" (aka "sloppy") group by implementation you might want to read these articles:
http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/
http://rpbouman.blogspot.de/2007/05/debunking-group-by-myths.html

Related

not self explicable 1064 error trying to use MEMBER OF in a mysql query

I have a query where I select some rows of a table based on their ID.
SELECT id,hotel_name FROM hotel WHERE id IN (1,2) and this works fine.
It returns two rows from hotel, id 1 and id 2 as expected. IDs in the where clause are hardcoded but data are coming from another table where they are stored in a json column as ["1","2"]. On a normal table i'd have done I'd have done (WHERE id in (SELECT ...) so I tried to replace the IN operator whith MEMBER OF that should behave like IN for JSON columns.
SELECT id,hotel_name FROM hotel
WHERE id MEMBER OF (
SELECT details FROM auth_events
WHERE auth_events.id_user=1 AND auth_events.id_auth_catalog=10
);
but I get
Syntax error in the query next to 'SELECT details FROM auth_events WHERE auth_events.id_user=1 AND auth_events.id_a'
but I don't understand exactly what is raising it. The inner query SELECT details FROM auth_events WHERE auth_events.id_user=1 AND auth_events.id_auth_catalog=10 is returning correctly the ["1","2"] array.
Can anyone help me understand what am I doing wrong? Also note that my mysql version is 8.0.26 and MEMBER OF is available since 8.0.13 so this shouldn't be the point
The operand of MEMBER OF must be scalar JSON array, not a rowset.
Use
SELECT id,hotel_name
FROM hotel
JOIN auth_events ON auth_events.id_user=1
AND auth_events.id_auth_catalog=10
AND hotel.id MEMBER OF (auth_events.details);
PS. The MEMBER OF() operator was added in MySQL 8.0.17, not in 8.0.13.

Check array contain at least all value of array

I got a question about MySQL query.
I have a table role and another table context. Each role could be linked with multiple context using a join table role_context. Example:
roleA->context1
roleA->context2
roleB->context1
I want a query to get all Roles that match all context I give. Example:
If I have ['context1'] in parameter I want ['roleA', 'roleB'] in result.
If I have ['context2'] in parameter I want ['roleA'] in result.
If I have ['context1', 'context2'] in parameter I want ['roleA'] in result.
I have tried to use
SELECT *
FROM role_context
INNER JOIN context ON role_context.context_name = context.name
WHERE context.name IN ["ETT","FR"]
But like it's an in it return roleA and roleB for my third condition.
Does someone have an idea for this query?
Or maybe my SQL architecture is not good?
The architecture is OK, its just that SQL does not have built-in operators for such tasks. You can use the following query to select roles that have all contexts in the given list (must be passed as an IN clause):
SELECT role_context.role_name
FROM role_context
JOIN context ON role_context.context_name = context.name
WHERE context.name IN ('context1', 'context2')
GROUP BY role_context.role_name
HAVING COUNT(context.name) = 2 -- here 2 corresponds to the number of items in the above list

MySQL can only use 61 tables in a join; How can I bypass this error for the following query?

I get a MySQL Error saying, I cannot use more than 61 tables in a join. I need to avoid this error. How do I do it? Please Help.
select
view_pdg_institutes.user_id as User_ID,
view_pdg_institutes.institute_id as Teacher_ID,
view_pdg_institutes.institute_name as Institute_Name,
view_pdg_institutes.user_email as Email,
view_pdg_institutes.contact_person_name as Contact_Person,
view_pdg_institutes.alternative_contact_no as Alternative_Mobile_No,
view_pdg_institutes.primary_contact_no as Mobile_No,
view_pdg_institutes.correspondance_address as Address,
view_pdg_institutes.other_communication_mode as Preferred_Contact_Mode,
view_pdg_institutes.size_of_faculty as Size_of_Faculty,
view_pdg_institutes.operation_hours_from as Operation_Hours_From,
view_pdg_institutes.operation_hours_to as Operation_Hours_To,
view_pdg_institutes.teaching_xp as Teaching_Experience,
view_pdg_institutes.installment_allowed as Installment_Allowed,
view_pdg_institutes.about_fees_structure as About_Fees_Structure,
view_pdg_institutes.no_of_demo_class as No_of_Demo_Classes,
view_pdg_institutes.demo_allowed as Demo_Allowed,
view_pdg_institutes.price_per_demo_class as Price_Per_Demo_Class,
view_pdg_tuition_batch.tuition_batch_id as Batch_ID,
view_pdg_batch_subject.subject_name as Subject_Name,
view_pdg_batch_subject.subject_type as Subject_Type,
view_pdg_batch_subject.academic_board as Academic_Board,
view_pdg_batch_fees.fees_type as Fees_Type,
view_pdg_batch_fees.fees_amount as Fees_Amount,
view_pdg_tuition_batch.course_days as Course_Days,
view_pdg_tuition_batch.days_per_week as Days_Per_Week,
view_pdg_tuition_batch.class_duration as Class_Duration,
view_pdg_tuition_batch.class_type as Class_Type,
view_pdg_tuition_batch.course_length as Course_Length,
view_pdg_tuition_batch.course_length_type as Course_Length_Type,
view_pdg_tuition_batch.no_of_locations as No_of_Locations,
view_pdg_tuition_batch.class_capacity_id as Class_Capacity_ID,
view_pdg_tutor_location.locality as Locality,
view_pdg_tutor_location.address as Address,
view_pdg_batch_class_timing.class_timing as Class_Timing
from view_pdg_tuition_batch
left join view_pdg_institutes on (view_pdg_tuition_batch.tutor_institute_user_id = view_pdg_institutes.user_id)
left join view_pdg_batch_subject on (view_pdg_batch_subject.tuition_batch_id = view_pdg_tuition_batch.tuition_batch_id)
left join view_pdg_batch_fees on (view_pdg_batch_fees.tuition_batch_id = view_pdg_tuition_batch.tuition_batch_id)
left join view_pdg_batch_class_timing on (view_pdg_batch_class_timing.tuition_batch_id = view_pdg_tuition_batch.tuition_batch_id)
left join view_pdg_tutor_location on (view_pdg_tutor_location.tuition_batch_id = view_pdg_tuition_batch.tuition_batch_id)
group by view_pdg_tuition_batch.tuition_batch_id;
I need a solution that would not require changing the current approach of writing the query.
I don't think it's possible to do what you're asking without some elaborate changes in the way you store and query data. You can
denormalize your DB to store JSON data;
create materialized views, emulating them via triggers, because they're absent in MySQL;
use temporary tables;
join partial selects by hand at the call site;
compile MySQL with another join limit;
use proper SQL engine like Postgres, that doesn't suffer from such stupid things.
Insert the contents of each view into its own temporary table. Then do the same query with the temporary table names substituted for the original view names.

mysql view super slow

this is the query for Unified Medical Language System(UMLS) to find a word related to normalized word. this query result is 165MS, but if I am running VIEW of this same query it is taking 70 sec. I m new to the mysql. Please help me.
Query:
SELECT a.nwd as Normalized_Word,
b.str as String,
c.def as Defination,
d.sty as Semantic_type
FROM mrxnw_eng a, mrconso b, mrdef c, mrsty d
WHERE a.nwd = 'cold'
AND b.sab = 'Msh'
AND a.cui = b.cui
AND a.cui = c.cui
AND a.cui = d.cui
AND a.lui = b.lui
AND b.sui = a.sui
group by a.cui
View definition:
create view nString_Sementic as
SELECT a.nwd as Normalized_Word,
b.str as String,
c.def as Defination,
d.sty as Semantic_type
FROM mrxnw_eng a, mrconso b, mrdef c, mrsty d
WHERE b.sab = 'Msh'
AND a.cui = b.cui
AND a.cui = c.cui
AND a.cui = d.cui
AND a.lui = b.lui
AND b.sui = a.sui
group by a.cui
Selection from view:
select * nString_Sementic
where nwd = 'phobia'
You may be able to get better performance by specifying the VIEW ALGORITHM as MERGE. With MERGE MySQL will combine the view with your outside SELECT's WHERE statement, and then come up with an optimized execution plan.
To do this however you would have to remove the GROUP BY statement from your VIEW. As it is, a temporary table is being created of the entire view first, before being filtered by your WHERE statement.
If the MERGE algorithm cannot be used, a temporary table must be used
instead. MERGE cannot be used if the view contains any of the
following constructs:
Aggregate functions (SUM(), MIN(), MAX(), COUNT(), and so forth)
DISTINCT
GROUP BY
HAVING
LIMIT
UNION or UNION ALL
Subquery in the select list
Refers only to literal values (in this case, there is no underlying
table)
Here is the link with more info. http://dev.mysql.com/doc/refman/8.0/en/view-algorithms.html
If you can change your view to not include the GROUP BY statement, to specify the view's algorithm the syntax is:
CREATE ALGORITHM = MERGE VIEW...
Edit: This answer was originally based on MySQL 5.0. I've updated the links to point to the current documentation, but I have not otherwise confirmed if the answer correct for versions >5.0.
Assuming that mrxnw_eng.nwd is functionally dependent on mrxnw_eng.cui, try changing the group by clause of the view to include a.nwd - like so:
group by a.cui, a.nwd

MySQL Inner Join should not produce results ... but it does

I've come across a situation where an incorrect query was generated:
select a.id, e.ethnicity_cd, e.appl_person_id from applicants a
inner join ucpsom_production_ucpsom_production.ETHNICITY e
on e.appl_person_id = a.id
where a.amc_id = 12977319
The error is in the join statement. The statement should read "e.appl_person_id = a.appl_person_id" and return no records because there is no e.appl_person_id value equal to "80cbacb2-8444-11df-acd2-12313b079cc4", the a.id value.
What is happening then is that MySQL is matching values of 80 (for e.appl_person_id) to values of "80cbacb2-8444-11df-acd2-12313b079cc4" (for a.id). Thus:
80 = "80cbacb2-8444-11df-acd2-12313b079cc4".
*Note: e.app_person_id is a decimal and a.id is a string.* It looks like MySQl is comparing the first two characters of the a.id value to the e.appl_person_id value.
Can anyone explain why this is happening with MySQL, and also, is this MySQL specific in nature?
Thanks much.
Looks like MySQL is attempting to do an implicit conversion of data types (from string to int in this case).
Most databases will do some conversions implicitly, for example SQL server will implicitly convert from smallint to int, but which conversions are done implicitly would be DBMS specific.