I have found the answer to my question, but in the wrong format.
Using SQL Alchemy I want to join columns from Table A to one column on Table B.
Table A contains two columns for Location Code. I can retrieve the Location Name by joining on to Table B, but how to do this?
So far I have this:
locationreq = sa.Table("INMPTL_LOCATION_REQUEST", meta.metadata,
sa.Column("request_id", sa.types.String(), primary_key=True),
sa.Column("status", sa.types.String(100)),
sa.Column("new_loc", sa.types.String(), sa.ForeignKey("INMPTL_LOCATIONS_TBL.inmptl_location_code")),
sa.Column("previous_loc", sa.types.String(), sa.ForeignKey("INMPTL_LOCATIONS_TBL.inmptl_location_code")),
autoload=True,
autoload_with=engine)
locationtable = sa.Table("INMPTL_LOCATIONS_TBL", meta.metadata,
sa.Column("INMPTL_LOCATION_CODE", sa.types.Integer(), primary_key=True),
autoload=True,
autoload_with=engine)
orm.mapper(Location, locationtable )
orm.mapper(LocationRequest, locationreq, extension= wf.WorkflowExtension(), properties = {'location':relation(Location)}
If only one of these columns were mapped to the second table, I could call something such as:
model.LocationRequest.location.location_name
But because I am mapping two columns to the same table, it is getting confused.
Does anyone know the proper way to achieve this?
I was going to delete this question, but this is not a duplicate. The answer is here (setting the primary and secondary joins)
orm.mapper(LocationRequest, locationreq, extension= wf.WorkflowExtension(),
properties={
"new_location":relation(Location,
primaryjoin=locationtable.c.inmptl_location_code==locationreq.c.new_loc, lazy = False),
"previous_location":relation(Location,
primaryjoin=locationtable.c.inmptl_location_code==locationreq.c.previous_loc, lazy = False)
})
Related
I am trying to delete some duplicate records from mysql table but it was not working.
I am taking help of https://www.javatpoint.com/mysql-delete-duplicate-records
If I will try with example database which is given example it was working fine.
But in my table it was not working.
DELETE S1 FROM employee_attendance AS S1 INNER JOIN employee_attendance AS S2 WHERE S1.DbKey < S2.DbKey AND S1.DivisionDbKey = S2.DivisionDbKey AND S1.Date = S2.Date AND S1.Month = S2.Month AND S1.FinancialYearDbKey = S2.FinancialYearDbKey AND S1.EmployeeDbKey = S2.EmployeeDbKey AND S1.Attendance = S2.Attendance AND S1.InTime = S2.InTime AND S1.OutTime = S2.OutTime AND S1.EmployeeDbKey = 6798 AND S1.Month = '05' AND S1.FinancialYearDbKey = 5;
I am getting error
#1205 - Lock wait timeout exceeded; try restarting transaction
I have tried with another example https://www.geeksforgeeks.org/sql-query-to-delete-duplicate-rows/
DELETE FROM employee_attendance WHERE DbKey NOT IN (SELECT MAX(DbKey) FROM employee_attendance WHERE EmployeeDbKey = 6798 AND Month = '05' AND FinancialYearDbKey = '5' GROUP BY DivisionDbKey,Date,Month,FinancialYearDbKey,EmployeeDbKey,Attendance,InTime,OutTime)
I am getting same error.
#1205 - Lock wait timeout exceeded; try restarting transaction
Any suggestion will be appriciated. Thank you.
I personally think this is a bad practice. You should instead make a (empty) duplicate of the table employee_attendance then define a UNIQUE KEY on that new table that will prevent duplicate entries.
Consider these steps:
Create a duplicate table:
CREATE TABLE employee_attendance_new LIKE employee_attendance;
Add UNIQUE INDEX - now, this is just a simple example. You can add or reduce columns to the unique index but make sure that you drop the existing unique index first then only you re-create:
ALTER TABLE employee_attendance_new
ADD UNIQUE INDEX unq_idx(EmployeeDbKey, date, InTime, OutTime);
Insert the data into the new table using INSERT IGNORE..:
INSERT IGNORE INTO employee_attendance_new
SELECT * FROM employee_attendance;
Check and compare both table. If you're satisfied with the result, rename those tables:
RENAME TABLE employee_attendance TO employee_attendance_old;
RENAME TABLE employee_attendance_new TO employee_attendance;
Now you have the new table with no duplicates and the old table for reference or in case there are some data you need from it.
Fiddle example
I am trying to copy all data from sqlite table to another one (reason being changing primary key and recommended way is to create new table, copy data, rename, etc).
Something along:
insert into new_table select * from old_table;
drop old_table;
alter table new_table rename to old_table;
Now problem is, that sometimes when I create new table, it's order of columns is not the same and data is completely messed up. Not sure why, probably cause some people have brand new table and some have old table which lived trough lot of upgrade scripts. Anyway my point is, I need to make sure every column is inserted into correct column. I can for sure just name all the columns manually, but I'd like this to work even if I add some columns in future and also for other tables. I can probably somehow query name of columns and then construct query in language that I am using above (kotlin), but I'd like to do this on db level if possible.
It's on android, but not very relevant to the question :)
Thanks!
Sadly I had add 1 extra query to get columns.
Other queries had all columns specifically mentioned instead of using star to ensure correct order. My kotlin way:
fun columns(db: SQLiteDatabase, tableName: String): List<String> {
val sql = "pragma table_info($tableName)"
return db.rawQuery(sql, arrayOf()).use { cursor ->
(1..cursor.count).map {
cursor.moveToNext()
cursor.getString(cursor.getColumnIndexOrThrow("name"))
}
}
}
fun copyFromTableToTable(db: SQLiteDatabase, originalTableName: String, backupTableName: String) {
val columns = columns(db, backupTableName).joinToString(separator = ",")
db.execSQL("""INSERT INTO $backupTableName
($columns)
SELECT $columns FROM $originalTableName
""".trimMargin())
//db.execSQL("DROP TABLE $originalTableName;")
//db.execSQL("ALTER TABLE $backupTableName RENAME TO $originalTableName;")
}
Is it possible to do the following query in SQLite.Swift without resorting to arbitrary SQL (which I do have working but would prefer to avoid)?
select table1.id, sum(table1.col1*table2.col2)
from table1, table2
where table1.id=table2.id
group by table1.id
I've attempted the following: the SQL (through asSQL()) appears to be correct, but I can't find a way to reference the aggregate column from the returned row.
let query = table1.select(id, (table1[column1]*table2[column2]).sum
.join(table2, on: table1[id] == table2[id])
.group(id)
Can you alias columns somehow?
OK, I've found the solution, and it only took me 2 days!
The way to alias a column in SQLite.swift is to use an expression.
The name of the expression becomes the column alias.
So instead of
let query = table1.select(id, (table1[column1]*table2[column2]).sum)
.join(table2, on: table1[id] == table2[id])
.group(id)
Use:
let aggrColumn = (table1[column1]*table2[column2]).sum
let query = table1.select(id, aggrColumn)
.join(table2, on: table1[id] == table2[id])
.group(id)
let results = try db.prepare(query)
for row in results {
myAggrColumn = try row.get(aggrColumn)
}
Using
select id, sum(table1.col1*table2.col2)
from table1, table2
were table1.id=table2.id
group by id
Will result (see below for corrections) in 2 columns, namely id and sum(table1,col*table2.col2)
However both uses of id would be ambiguous as coded as there are two such source columns.
As such the query should be changed (see following code whihc assumes you want the id from table1 (shouldn't matter if table2 were used due to the join))
Additionally were is not a keyword, it should be WHERE
An alias would likely make things easier you make an alias using the AS keyword. The folloiwng also includes AS mysumcolumn thus the resultant columns will be id and mysumcolumn
select table1.id, sum(table1.col1*table2.col2) AS mysumcolumn
from table1, table2
where table1.id=table2.id
group by table1.id
Running this with no data results in :-
Using SQLite, I am trying to update three columns based on another table (two columns)
The three columns are (Table1):
'AgentCreatedID'
'AgentOwnedID'
'AgentSentID'
The other table (Table2) consists of 'AgentID' and 'Designation'.
If the ID in one of the three columns matches the 'AgentID' in the second table, I want the 'Designation' value to populate. This table is a list of ALL unique IDs and the corresponding designation. Each row of data has a Creator, Owner, and Sender. I need to see what designation that person is from.
In Access, this would look something like this for the first value. I would also need to add the other two values.
UPDATE Table1
LEFT JOIN Table2 ON Table1.AgentCreatedID = Table2.AgentID
SET raw.AgentCreatedID = [ Table2 ]![ Designation];
I am not sure what that ! command is or how it could be used in SQLite.
SQLite does not suport joins in an UPDATE statement.
You have to look up the new value with correlated subqueries:
UPDATE Table1
SET AgentCreatedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentCreatedID),
AgentOwnedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentOwnedID),
AgentSentID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentSentID)
The exclamation mark is used to separate the worksheet name from the reference in that worksheet. Here is Microsoft's explanation of cell references.
Now that you know what [ Table2 ]![Designatio] means, you can simplify it to use only the column name.
I am using it but no value i found...I think there is mistake in this query....Actually I want to know how to use multiple sum, multiplication etc using mutiple tables in sqlite
SELECT
dhid, dprice, dname,
SUM(dmilk) AS totalmilk,
dprice*SUM(dmilk) AS totalmilkamt,
SUM(ghee) AS toalghee,
SUM(ghee*gheeprice) AS totalgheeamt,
SUM(ghee*gheeprice)+dprice*SUM(dmilk) AS totals,
SUM(cashamount) AS totalcash,
SUM(ghee*gheeprice)+dprice*SUM(dmilk)-SUM(cashamount) AS balance
FROM
( SELECT *
FROM costumer
LEFT OUTER JOIN salesdata
ON costumer.dhid=salesdata.ddhid
LEFT OUTER JOIN cashdata
ON salesdata.ddhid=cashdata.uid
AND utype='costumer')
WHERE dmonth='$mikdatem'
AND dyear='$mikdatey'
AND dhid='$dhid'
ORDER BY dhid ASC
Your select above will not help us because we don't have the underlying data to get an idea what you wish to do.
So the generalistic answer is this:
when using grouping-functions (SUM/COUNT...) you always require some form of "GROUP BY" to columns not used in those group-functions.
Example given:
SELECT name, sum(dmilk)
FROM milk_entry
GROUP BY name