sqlalchemy: select specific columns from multiple join using aliases - sql

This has be stumped for more than a day now and examples I could find have not worked. I am new to SQLALCHEMY and I find the documentation not very enlightening.
The query (so far):
prey = alias(ensembl_genes, name='prey')
bait = alias(ensembl_genes, name='bait')
query = db.session.query(tap,prey,bait).\
join(prey, tap.c.TAP_PREY_ENSEMBL_GENE_ID==prey.c.ENSEMBL_GENE_ID).\
join(bait, tap.c.TAP_BAIT_ENSEMBL_GENE_ID==bait.c.ENSEMBL_GENE_ID).\
filter(\
or_(\
tap.c.TAP_PREY_ENSEMBL_GENE_ID=='ENSG00000100360',\
tap.c.TAP_BAIT_ENSEMBL_GENE_ID=='ENSG00000100360'\
)\
).\
order_by(desc(tap.c.TAP_UNIQUE_PEPTIDE_COUNT))
tap refers to a table of interacting genes. One interactor is designated the 'bait' and the other the 'prey'. Prey and Bait are aliases for the same table that holds additional information on these genes. The objective is to select all interactions with a given gene 'ENSG00000100360' as either bait or prey.
The problem:
This query returns about 20 or so columns, but I need only six specific ones, two from each original tables (I'd like to rename them as well). From examples found on the interwebz I thought I should add:
options(
Load(tap).load_only('TAP_UNIQUE_PEPTIDE_COUNT','TAP_SEQUENCE_COVERAGE'),
Load(prey).load_only('ENSEMBL_GENE_SYMBOL','ENSEMBL_GENE_ID'),
Load(bait).load_only('ENSEMBL_GENE_SYMBOL','ENSEMBL_GENE_ID')
)
But this gives me the following error:
File "/Users/jvandam/Github/syscilia/tools/BDT/quest/blueprints/genereport.py", line 246, in createTAPMSView
Load(tap).load_only('TAP_UNIQUE_PEPTIDE_COUNT','TAP_SEQUENCE_COVERAGE')
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/strategy_options.py", line 82, in init
self.path = insp._path_registry
AttributeError: 'Table' object has no attribute '_path_registry'
I have not been able to find anything on google about what to do about this.
The sqlalchemy table objects are created from the database table metadata.
What I am trying to emulate using the sqlalchemy orm statements is:
SELECT
prey.ENSEMBL_GENE_SYMBOL AS PREY_ENSEMBL_GENE_SYMBOL,
prey.ENSEMBL_GENE_ID AS PREY_ENSEMBL_GENE_ID,
bait.ENSEMBL_GENE_SYMBOL AS BAIT_ENSEMBL_GENE_SYMBOL,
bait.ENSEMBL_GENE_ID AS BAIT_ENSEMBL_GENE_ID,
t.TAP_UNIQUE_PEPTIDE_COUNT AS UNIQUE_PEPTIDE_COUNT,
t.TAP_SEQUENCE_COVERAGE AS SEQUENCE_COVERAGE
FROM TAP as t
INNER JOIN ENSEMBL_GENES AS prey
ON tap.TAP_PREY_ENSEMBL_GENE_ID=prey.ENSEMBL_GENE_ID
INNER JOIN ENSEMBL_GENES AS bait
ON t.TAP_BAIT_ENSEMBL_GENE_ID=bait.ENSEMBL_GENE_ID
WHERE
t.TAP_PREY_ENSEMBL_GENE_ID='ENSG00000100360'
OR t.TAP_BAIT_ENSEMBL_GENE_ID='ENSG00000100360'
ORDER BY t.TAP_UNIQUE_PEPTIDE_COUNT DESC
Can anyone help me fix my query?
Thanks in advance!
John

Just change this part db.session.query(tap,prey,bait).\ with the below:
db.session.query(\
prey.ENSEMBL_GENE_SYMBOL.label("PREY_ENSEMBL_GENE_SYMBOL"),
prey.ENSEMBL_GENE_ID.label("PREY_ENSEMBL_GENE_ID"),
bait.ENSEMBL_GENE_SYMBOL.label("BAIT_ENSEMBL_GENE_SYMBOL"),
bait.ENSEMBL_GENE_ID.label("BAIT_ENSEMBL_GENE_ID"),
tap.TAP_UNIQUE_PEPTIDE_COUNT.label("UNIQUE_PEPTIDE_COUNT"),
tap.TAP_SEQUENCE_COVERAGE.label("SEQUENCE_COVERAGE"),
).\
select_from(tap).\ # #note: need this in so that FROM and JOINs are in desired order
This will select only the columns you need.

Related

Microsoft SQL Server generates two select queries and puts data in separate columns

I am looking for a query that separate the data with the condition WHERE in the same output but in separates columns.
Example: I have the table Product_2:
I have two separates queries (to separate the products by Produt_Tag):
SELECT
Product_Mark AS "PIT-10_Product_Mark",
Product_Model AS "PIT-10_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-10';
SELECT
Product_Mark AS "PIT-11_Product_Mark",
Product_Model AS "PIT-11_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-11';
And I get this output:
But I need the output to be like this:
Can someone tell me how I need to modify my query to have the four columns in the same table/ output?
Thank you
I forgot to tell that in the data I Have the “Porduct_Mark” that only appears one time. (in reality the data in “Product_Mark” is the name of the place where the instrument is located and one place can have one or two instruments “Product_Model”. At the end I’m looking for the result show in the image here below. I tried to use LEFT JOIN but that don’t work.
here is the new table "Product_2"
Result that I'm looking for:
Luis Ardila
I am assuming Product_PK is the primary key for the table and the repeated value 1002 shown in the question is a mistake. Considering this assumption, you can get the result set using self join as below.
SELECT pa.Product_Mark AS "PIT-10_Product_Mark", pa.Product_Model AS "PIT-10_Product_Model",
pb.Product_Mark AS "PIT-11_Product_Mark", pb.Product_Model AS "PIT-11_Product_Model"
FROM Product_2 pa
INNER JOIN Product_2 pb
ON pa.Product_Mark = pb.Product_Mark
WHERE pa.product_pk != pb.product_pk
and pa.Product_Tag = 'PIT-10'
and pb.Product_Tag = 'PIT-11';
verified same in https://dbfiddle.uk/NiOO8zc1

How to fix Column does not exist on this Inner Join of two tables with three conditions?

Currently, I am trying to create a new table based on the Inner Join query of two tables with three conditions. However, the SQL Error window always tells me the columns does not exist even when they clearly do.
So this is what has to happen an Inner Join has to happen when two specific values are equal to each other in the table of the columns and where are third value shares a similarity.
This is because while the Plotletter in the first table is actually only one letter like for say A.
The Application could be written like ABCD.
I have already also tried to make the clear the fields are referred to the right table by following the suggestion, but the error still happens.
CREATE TABLE testschema.FinalPlantenpaspoort
AS
SELECT PrimaryIndex, jaarpr, proefcode, plotleter, plotcijfer, plot, X, Y
FROM testschema.plantenpaspoortsjabloon
JOIN testschema.weegschaalproeven
ON plantenpaspoortsjabloon.proefcode = weegschaalproeven.Intern_Proef_Nr
AND plantenpaspoortsjabloon.plotcijfer = weegschaalproeven.Objectnr
WHERE plantenpaspoortsjabloon.plotletter LIKE weegschaalproeven.Application
;
This the error and suggestion they give me but no luck.
ERROR: column weegschaalproeven.intern_proef_nr does not exist
LINE 5: ON plantenpaspoortsjabloon.proefcode = weegschaalproeven.Int...
^
HINT: Perhaps you meant to reference the column "weegschaalproeven.Intern_Proef_Nr".
SQL state: 42703
Character: 237
**
Edit 2/07/2019: PROBLEM HAS BEEN SOLVED BUT 0 RECORDS Selected.
**
Okay the problem seems to be solved but there is a new kind of problem while the code does works 0 records are selected because of the JOIN. And this should not be the case. I know there are records that matches because this a test where I made sure the tables of the shapefiles in QGIS contains data that is relevant.
Create TABLE testschema.finalplantenpaspoort AS
SELECT jaarpr, proefcodet, plotletter, plotcijfer, plot, X, Y
FROM testschema.plantenpaspoortsjabloon
JOIN testschema.weegschaalproeven
ON plantenpaspoortsjabloon.proefcodet = weegschaalproeven.intern_proef_nr AND plantenpaspoortsjabloon.plotcijfer = weegschaalproeven.objectnr
WHERE plantenpaspoortsjabloon.plotletter LIKE weegschaalproeven.application
;
**SELECT 0**
Query returned successfully in 72 msec.
I have found the sollution to my zero select problem, apparently I needed to set a special Like circumstance because otherwise the records could not be matched here it goes:
Create TABLE testschema.finalplantenpaspoort AS
SELECT proefcodet, proefnaam, datumvernietiging, oogstvernietigingsmethode, objectnr, productcode, potnummer, dosis, oppervlakte, eenheid, luikb, oogstbestemming, application, opmerking, proefjaar, proefcode, plotletter, plotcijfer, plot, X, Y
FROM testschema.plantenpaspoort
JOIN testschema.weegschaalproeven
ON plantenpaspoort.proefcode = weegschaalproeven.internproefnr AND plantenpaspoort.plotcijfer = weegschaalproeven.objectnr AND plantenpaspoort.plotletter LIKE ANY (regexp_split_to_array(weegschaalproeven.application , '\s*'))
;
GRANT ALL ON TABLE testschema.finalplantenpaspoort TO test_admin_test WITH GRANT OPTION;

SQL Query not searching data if record contains zero

I have two tables and with column paperNo and some data regarding that paper. I am trying to search all data based on paper no. from both the tables. I have successfully written the query and it is retrieving the data successfully. but I have noticed that. If my paperNo contains zero(0) then the query is not searching for that data. And for the non zero contains paperNo it is retrieving the same record twice.
I don't understand what is going wrong. tried every thing.
Here is my Query .-
SELECT PaperDate.paperNo,
PaperDate.RAW_PAPER,
PaperDate.EDGE_SEALED,
PaperDate.HYDRO_120,
PaperDate.HYDRO_350,
PaperDate.CATALYST_1ST,
PaperDate.CATALYST_2ND,
PaperDate.SIC_350,
tblThicknessPaperDate.rawThickness,
tblThicknessPaperDate.catThickness,
tblThicknessPaperDate.sicThickness,
tblThicknessPaperDate.rejectedThickness
FROM tblThicknessPaperDate
FULL OUTER JOIN PaperDate ON PaperDate.paperNo =tblThicknessPaperDate.paperNo
WHERE (tblThicknessPaperDate.paperNo = #paperNo)
I would try:
FROM tblThicknessPaperDate
RIGHT JOIN PaperDate ON PaperDate.paperNo =tblThicknessPaperDate.paperNo
WHERE (PaperDate.paperNo = #paperNo)
The two changes are: swapping to a right join so even if a record isn't in tblThicknessPaperDate we will still see the record in PaperDate. The other change is to use PapterDate.paperNo in the where clause. Since tblThicknessPaperDate.paperNo could be null we don't want to use that in the where if we can avoid it.
SELECT PaperDate.paperNo,
PaperDate.RAW_PAPER,
PaperDate.EDGE_SEALED,
PaperDate.HYDRO_120,
PaperDate.HYDRO_350,
PaperDate.CATALYST_1ST,
PaperDate.CATALYST_2ND,
PaperDate.SIC_350,
tblThicknessPaperDate.rawThickness,
tblThicknessPaperDate.catThickness,
tblThicknessPaperDate.sicThickness,
tblThicknessPaperDate.rejectedThickness
FROM tblThicknessPaperDate
FULL OUTER JOIN PaperDate ON PaperDate.paperNo =tblThicknessPaperDate.paperNo
WHERE (tblThicknessPaperDate.paperNo = #papNo | PaperDate.paperNo = #paperNo)

SQL - Getting a column from another table to join this query

I've got the code below which displays the location_id and total number of antisocial crimes but I would like to get the location_name from a different table called location_dim be output as well. I tried to find a way to UNION it but couldn't get it to work. Any ideas?
SELECT fk5_location_id , COUNT(fk3_crime_id) as TOTAL_ANTISOCIAL_CRIMES
from CRIME_FACT
WHERE fk1_time_id = 3 AND fk3_crime_id = 1
GROUP BY fk5_location_id;
You want to use join to lookup the location name. The query would probably look like this:
SELECT ld.location_name, COUNT(cf.fk3_crime_id) as TOTAL_ANTISOCIAL_CRIMES
from CRIME_FACT cf join
LOCATION_DIM ld
on cf.fk5_location_id = ld.location_id
WHERE cf.fk1_time_id = 3 AND cf.fk3_crime_id = 1
GROUP BY ld.location_name;
You need to put in the right column names for ld.location_name and ld.location_id.
you need to find a relationship between the two tables to link a location to crime. that way you could use a "join" and select the fields from each table you are interested in.
I suggest taking a step back and reading up on the fundamentals of relational databases. There are many good books out there which is the perfect place to start.

Produce a Query viewing multiple tables

I have been given a database, the structure and data values are all unchangable and have been provided with a question.
Produce a query to list the holiday code, holiday description, holiday duration and site description for all holidays which visit site code 101. Your answer must not assume that site code 101 will always have the same site description.
I am confused on how to tackle this question. I have tried Multiple joins, different dot notation and googled the question to hell and back. Any help?
Table 1 - Holiday_Details
Holiday_Code - Country_Visited - Holiday_Duration - Holiday_Desc - Rating_Code - Cost
Table 2 - Site_Of_Holiday
Site_Description - Site_Code
Table 3 - Site_Visited
Holiday_Code - Site_Code
Comments have asked for previous attempts. This was my first.
SELECT holiday_code,
holiday_desc,
holiday_duration site_of_holiday.Site_Name
FROM holiday_details
JOIN site_visited
ON holiday_code = site_visited.holiday_code
JOIN site_of_holiday
ON site_visited.site_code = site_of_holiday.site_code
WHERE site_of_holiday.site_code = 101;
For future reference, you'll get a better response if you post a lot more detail about your failed attempts. By that, I mean code. Using SO to solve your homework assignments is frowned upon but, like a commenter said, once you've wracked your brain we're willing to help.
You seem like you may have actually tried real hard, so I'll throw you a bone...
The trick to navigating multiple tables is to find the "pairs" of matching columns. In this case you want to find a path between the tables Site_Of_Holiday (which has Site_Description) and Holiday_Details (which has everything else).
The columns that match between each pair of tables are:
Holiday_Code is found in both Site_Visited and Holiday_Details
Site_Code is found in both Site_Of_Holiday and Site_Visited
This allows you to build a path between the tables that contain all of the columns we want in the output. You would do this, in this case, using INNER JOINs across those matching column pairs.
Once you've joined the tables, think of the result like a giant table whose columns include all columns from all three tables (prefixed with whatever you 'name' the table during the joins). Now you just filter on the Site_Code with the usual WHERE clause.
Here's the full example - let me know if it works for you:
SELECT hd.Holiday_Code, hd.Holiday_Desc, hd.Holiday_Duration, soh.Site_Description
FROM Holiday_Details hd
INNER JOIN Site_Visited sv ON hd.Holiday_Code = sv.Holiday_Code
INNER JOIN Site_Of_Holiday soh ON sv.Site_Code = soh.Site_Code
WHERE sv.Site_Code = 101
Good luck!
P.S. In case any Americans get a similar assignment, here's the translation ;-)
SELECT vd.Vacation_Code, vd.Vacation_Desc, vd.Vacation_Duration, sov.Site_Description
FROM Vacation_Details vd
INNER JOIN Site_Visited sv ON vd.Vacation_Code = sv.Vacation_Code
INNER JOIN Site_Of_Vacation sov ON sv.Site_Code = sov.Site_Code
WHERE sv.Site_Code = 101