SQLAlchemy query from multiple tables - sqlalchemy

I am trying to query from two tables.. my appointments and clients. the client number is my foriegn key in appointments that I can pull from the clients database on.
Right now, I am just returning guests to see what it is doing, I am getting this error:
TypeError: repr returned non-string (type tuple)
#app.route('/calendar')
def weeklycal():
weekyrnum=request.args.get('weekyr')
guests = db.session.query(Appointments,Clients).filter(Appointments.clientnumber == Clients.clientnumber).filter(Appointments.weekyr == weekyrnum).all()
return
render_template(calbyWeek.html",guests=guests)
How can I query everything from appointments and clients with clientnumber being the column to join on (which is defined as the foreign key in Appointments model), and filter by the week?

Reference the individual columns from multiple tables in you query, plus make sure you join to additional tables.
guests=db.session.query(Appointments.time,Clients.name).join(Clients).filter(Appointment.clientnumber==Clients.clientnumber).filter(Appointments.weekyr==weekyrnum).all()
If all you actually want is the guests but use Appoitments in you filter then you also just need to add a join.
guests=db.session.query(Clients).join(Appointments).filter(Appointments.clientnumber==Clients.clientnumber).filter(Appointments.weekyr==weekyrnum).all()

Related

Why and how do these two queries both work

I have been trying to learn SQL using SQLBolts tutorial and for this exercise, I needed to write a query that showed the names of all the buildings with no employees using only LEFT JOIN. I had an answer different from the website and I am wondering why they both work. The only difference between our solutions is I put WHERE buildings is NULL vs SQL Bolts solution of WHERE role is null. If building value is null shouldn't that return a null value? Also same with role how does the Database know a building has a null value for role when there isn't a building attached to that role?
my query
SELECT building_name
FROM buildings
LEFT JOIN EMPLOYEES
ON buildings.building_name = EMPLOYEES.building
WHERE building IS NULL
SQL BOLT query
SELECT DISTINCT building_name, role
FROM buildings
LEFT JOIN employees
ON building_name = building
WHERE Role IS NULL
Buildings (table1) and Employees (table2)
Null Values from Database
Formally both queries are incorrect until complete tables structures are defined. When the query datasource includes more than one table copy then each column name must be specified with its table alias part. Exclusion - the column names used in USING clause or common columns when NATURAL JOIN is used, these columns may be used without table aliases. Backward exclusion - the query is used in compound statement, and local variables are present, in this case aliases must be used unconditionally.
If the tables structures claims that the queries texts are correct (all columns which have no table aliases are unique) then your query is more correct because it uses the column used in JOIN condition while testing for NULL. The "SQL BOLT query"may give wrong result if Role column is nullable and some rows contains NULL in this column.
If Role is defined as NOT NULL (directly or indirectly - for example, by according CHECK constraint, or it is a part of primary key) then both queries will give the same output.

MySQL: "Adding/Substracting strings in dialect 3" - error when operating on numeric fields?

I have a Service table and a Payments table. I want my clients to be able to pay for one service with multiple payments, but when I try to create a form for making a payment, I'm unable to make a
"ServiceA"."Cost" - SUM("Payment"."Amount")
substraction in my SELECT query that would show the amount left to pay. I'm being told Strings cannot be added or subtracted in dialect 3 even though all the relevant fields are Numeric, with the same amount of decimal points and everything...
Any idea on what I might be doing wrong?
EDIT:
More details. The relevant tables are actually as follows:
ServiceA, ServiceB, ServiceC, ServiceD all have a numeric field Cost. Their primary keys are actually foreign keys - they are all tied to an auto_increment BIGINT field in a table For. This is for the purpose of giving them auto_incrementing, yet non-repeating IDs.
There's a table PS (stands for Payment-Service) functions as a intermediate table for a multi-multi relationship. It has two foreign keys - one from Payments and one from For. This gives me the option to have multiple payments for one service or to have one payment cover multiple services.
Additionally, every Service table has a field referencing the ID of the client from "Clients".
In my SELECT, I try to do the following:
SELECT "Clients"."Name" || ': ' || "ServiceA"."Name" || ' for ' || "ServiceA"."Cost" - SUM("Payments"."Amount") AS "To-Pay", "ID-Name" AS "ID"
FROM "ServiceA"
LEFT OUTER JOIN "Clients" ON "ServiceA"."Client" = "Clients"."ID-Client"
INNER JOIN "For" ON "ServiceA"."Id-ServA" = "For"."ID"
LEFT OUTER JOIN "PS" ON "For"."ID" = "PS"."For"
LEFT OUTER JOIN "Payments" ON "PS"."Payment" = "Payments"."For"
GROUP BY "To-Pay, "ID"
HAVING "PS"."Payment" IS NULL OR **SUM("Payments"."Amount") < "ServiceA"."Cost"
UNION ALL
(like the above but with other "Service" tables)
ORDER BY "To-Pay"
This is for a dropdown list in a Create Payment form. It seems the problematic parts are the ones in bold.
Try to change this
"ServiceA"."Cost" - SUM("Payment"."Amount")
to this
`ServiceA`.`Cost` - SUM(`Payment`.`Amount`)
Or cast it to a specific type
CAST("ServiceA"."Cost" AS DECIMAL(12,2)) - CAST(SUM("Payment"."Amount") AS DECIMAL(12,2));

SQL- Remove symmetrical duplicates

I have a database table called rates with four foreign keys and a decimal amount (primary key is understood). I am using MY-SQL database 5.6.17. I suspect that the data contains duplicate amounts for reverse combinations point_id_2 and point_id_2. The other two foreign keys,method_id and class_id seem to be mirrored in the respective tuples which appear to have duplicate amounts. See the image below.
If you look at the foreign keys,point_id_1, point_id_2 and the amount this is what I mean by "symmetrical data".
Is it possible to track down all rows where point_id_1 and point_id_2 are interchanged and the amounts are the same?
This way I can then decide on which rows to remove.
So you just want to know if you have duplicates on the two POINT_ID fields for the same amount? You just need a simple join on the fields you think are matching:
SELECT r1.*, r2.*
FROM
rates r1
INNER JOIN rates r2
ON r1.point_ID_1 = r2.point_ID_2 AND r1.point_ID_2 = r2.point_ID_1
WHERE
r1.amount = r2.amount

Match data from two tables and return results where something matchs

Update 4/25/13 6:25AM: I am using MyISAM
I have searched a lot and am not sure the best way to do this. I have two tables that have matching values in different columns and need to return all that apply to where clause.
Table 1 name agent
Relevant Column Names agent_name and team
Table 2 name poll_data
Relevant Column Names agent and duid
So I want to count how many poll results I get from each teambut I need to somehow add the team from agent table to poll_data by matching the agent.agent_name to poll_data.name so I can return only data for that team. How can I match the records and then search them in a single query.
try this ...
$query1="SELECT COUNT(*) FROM poll_data JOIN agent ON (poll_data.agent = agent.agent_name) GROUP BY agent.team";
you should normalize the database using foreign key.

Composite key for multiple tables: do I need a separate query to check table type?

I have a db model similar to this: Foreign key for multiple tables.
I have account table. An account may be of type venue or band. I decided to make a composite key in account table: id_account | type - together they'd make up a PK (type may be venue or band or their numeric equivalents)
I know how I'd e.g. select all venues with data from account table as well: SELECT account.*, venue.* FROM venue INNER JOIN account ON (venue.id=account.id AND type=venue).
Now, I have an administration panel in which user has his account (which is one of those type - venue or band). When he logs, the panel is different for venue accounts and for bands accounts. Do I need one query to check the type of account (let's say it's venue) and then another query to the venue table to grab his data? Otherwise - can I do something similar to:
SELECT ... FROM IF(type=venue, venue, band)
There are several approaches to this. It's probably not too expensive to do the two queries but if you want you could join the 'account' query to both 'band' and 'venue' tables (by some unique ID for either) then take the appropriate column from the result depending on the 'account type' column in the result.