Peewee join query can't get data - peewee

I have the following 2 tables in my database.
tbl_customers
cid (int auto)
name (text)
tbl_contacts
cid
email
name
phone
I am trying to write the following sql query in peewee, but just can't get it to work
SELECT tbl_customers.cid, tbl_contacts.name
FROM tbl_customers
INNER JOIN tbl_contacts ON tbl_customers.cid = tbl_contacts.cid
WHERE tbl_customers.cid = '5';
I am trying to get the data to display like this
tbl_customer.cid = 5
tbl_contacts.name = 'Test User'
I tried the following in peewee, based on google searches that i am finding.
tbl_customers.select(tbl_customers.cid, tbl_contacts.name).join(tbl_contacts, on=(tbl_customers.cid == tbl_contacts.cid)).where(tbl_customers.cid == '5')

Peewee automatically puts your models into a graph, so the contact name would be accessed something like:
customer.contact.name
If you just want all data on a single model instance, you can append ".objects()" to your query and it will put all the column data on the instance-type being selected.
This is documented thoroughly:
http://docs.peewee-orm.com/en/latest/peewee/relationships.html#selecting-from-multiple-sources

Related

Return Count if linked table does not contain specific value

I am linking two tables in Microsoft SQL Server. The one table contains documents and the other contains the event status, which I need to specify a condition.
On the documents table, I am looking at the document code which is linked to the event, for example 371268-INV-1 and 371268-INV-1-APPROVED. There should be 2 documents per event.
I need to return values/ counts where the status from the Events table is approved but where there is no document code containing Approved.
I started out using:
select * from Documents
join EVENTS on event_code = left (document_code, 6)
where document_code like '371268%' and Event_Status = 'Approved'
This will get all events that are approved that do not have 2 records in the documents table. I think this will get you the results you are looking for.
select *
from events
where event_status = 'approved'
and event_code not in(select left (document_code, 6)
from documents
group by left (document_code, 6)
having count <>2)
If I correctly understand, this is what you need
select * from Documents
join EVENTS on event_code = left (document_code, 6)
WHERE
EVENTS.Event_Status = 'Approved' AND Documents.document_code NOT LIKE '%APPROVED';

TSQL query to filter directory

I'm trying to create a business directory in which I'm using the following query to pull data from 2 tables that contain the business info.
select *
from BND_Listing
left join BND_ListingCategories on BND_Listing.CatID = BND_ListingCategories.CatID
order by Company asc
I have a form that has 3 dropdowns I'm using to filter the above query using "Filters" that really are just components I need to add to my query above that will listen to query string values passed in by the form.
On submit of my form I'm redirecting back to the same URL but adding the following in my URL based on values selected from 3 dropdown fields.
filter-Category=[Category]&filter-City=[City]&filter-State=[State]
I've got this working correctly but am having difficulties when no value is passed into my URL. This happens when a user filters only by 1 of the 3 possible fields. To fix this I'm thinking I can create an "All" value that would be like filter-State=ALL
How can I update my query to pull data to listen for these filters in the query-string?
Any insight, examples really appreciated.
Hope I make sense I'm still new to programming.
The following query returns 0 results until all filters are set. If only 1 filter is set it crashed my application.
select *
from BND_Listing
where
(Category = '[querystring:filter-Category]'
or '[querystring:filter-Category]'='All')
and
(City = '[querystring:filter-City]'
or '[querystring:filter-City]'='All')
and
(State = '[querystring:filter-State]'
or '[querystring:filter-State]'='All')
UPDATE:
Thanks for all the input everyone.
I've tried this simplified query in SQL Server Management Studio to test.
SELECT *
FROM BND_listing
WHERE city = IsNull('Trinity', city)
It returns no results even though 'Trinity' is in fact a city in one of my records in the BND_Listing table.
I understand the ALL would add more filters but this basic query is still not pulling anything?
UPDATE 2:
On page load where I have not pressed the sort button and there are no query string values passed yet. If I want my grid to load ALL table records should I use a UNION command for my basic query.
select *
from BND_Listing
Plus the more complex query used for filtering the results? So far all query examples below pull in nothing from my grid because of the WHERE statement.
Are you limited to just a select query that has to be placed in the plug-in? If not, I would create a stored procedure and read up on dynamic SQL. Dynamic SQL would allow you to dynamically generate and execute a completely different query based on whatever conditions you specify. With dynamic SQL, you could also dynamically generate the entire predicate instead of having to hard code each condition.
Another (less efficient) alternative would be to use LIKE instead of = in your predicate. For example:
SELECT *
FROM BND_Listing
WHERE Category LIKE CASE
WHEN [querystring:filter-Category] = 'All' THEN '%'
ELSE '[querystring:filter-Category]'
END
AND City LIKE CASE
WHEN [querystring:filter-City] = 'All' THEN '%'
ELSE '[querystring:filter-City]'
END
AND State LIKE CASE
WHEN [querystring:filter-State] = 'All' THEN '%'
ELSE '[querystring:filter-State]'
END
Assuming you want to search for 'All' for a given category when no filter is present, you can just treat an empty filter as meaning all:
SELECT *
FROM BND_Listing
WHERE (Category = '[querystring:filter-Category]' OR
'[querystring:filter-Category]' = 'All' OR
COALESCE([querystring:filter-Category], '') = '') AND
(City = ... )
...
Perhaps you could try something like this.
SELECT *
FROM BND_listing
WHERE category = IsNull('[querystring:filter-Category]', category)
AND city = IsNull('[querystring:filter-City]', city)
AND state = IsNull('[querystring:filter-State]', state)
This functionality will check for an active filter if present and compare the appropriate field to ensure it matches.
In the case the filter has not been set it will compare the field to itself so it will always return a true result.
When you want all the records when the input is NULL then handle it using IS NULL.
SELECT *
FROM BND_listing
WHERE (category = '[querystring:filter-Category]' OR [querystring:filter-Category]' is NULL)
AND (city = '[querystring:filter-City]' OR '[querystring:filter-City]' IS NULL)
AND (state ='[querystring:filter-State]' OR '[querystring:filter-State]' IS NULL)
Note : This method will use any INDEX present on Category or city or state where as ISNULL or COALESCE method will restrict the optimizer from using INDEX

NHibernate Criteria SQL Inner Join on Sub Select Same Table

I can't for the life of me figure out how to translate the following SQL query using NHibernate's Criteria API:
SELECT r.* from ContentItemVersionRecords as r
INNER JOIN (
SELECT ContentItemId as CID, Max(Number) as [Version]
FROM ContentItemVersionRecords
GROUP BY ContentItemId
) AS l
ON r.ContentItemId = l.CID and r.Number = l.[Version]
WHERE Latest = 0 and Published = 0
The table looks like this:
The result of the SQL query above will return the highlighted records.
The idea is to select the latest version of content items, so I basically need to group by ContentItemId and get the record with the highest Number.
So the result will look like this:
I started out with a detached criteria, but I am clueless as to how to use it in the criteria:
// Sub select for the inner join:
var innerJoin = DetachedCriteria.For<ContentItemVersionRecord>()
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContentItemId"), "CID")
.Add(Projections.Max("Number"), "Version"));
// What next?
var criteria = session.CreateCriteria<ContentItemVersionRecord>();
Please note that I have to use the Criteria API - I can't use LINQ, HQL or SQL.
Is this at all possible with the Criteria API?
UPDATE: I just came across this post which looks very similar to my question. However, when I apply that as follows:
var criteria = session
.CreateCriteria<ContentItemVersionRecord>()
.SetProjection(
Projections.ProjectionList()
.Add(Projections.GroupProperty("ContentItemId"))
.Add(Projections.Max("Number")))
.SetResultTransformer(Transformers.AliasToBean<ContentItemVersionRecord>());
I get 2 results, which looks promising, but all of the integer properties are 0:
UPDATE 2: I found out that if I supply aliases, it will work (meaning I will get a list of ContentItemVersionRecords with populated objects):
var criteria = session
.CreateCriteria<ContentItemVersionRecord>()
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Max("Id"), "Id")
.Add(Projections.GroupProperty("ContentItemId"), "ContentItemId")
.Add(Projections.Max("Number"), "Number"))
.SetResultTransformer(Transformers.AliasToBean<ContentItemVersionRecord>());
However, I can't use the projected values as the end result - I need to use these results as some sort of input into the outer query, e.g.
SELECT * FROM ContentItemVersionRecord WHERE Id IN ('list of record ids as a result from the projection / subquery / inner join')
But that won't work, since the projection returns 3 scalar values (Id, ContentItemId and Number). If it would just return "Id", then it might work. But I need the other two projections to group by ContentItemId and order by Max("Number").
OK, so in a nutshell, you need to unwind that nested query, and do a group by with a having clause, which is pretty much a where on aggregated values, as in the following HQL:
SELECT civ.ContentItem.Id, MAX(civ.Number) AS VersionNumber
FROM ContentItemVersionRecord civ
JOIN ContentItem ci
GROUP BY civ.ContentItem.Id " +
HAVING MAX(civ.Latest) = 0 AND MAX(civ.Published) = 0
This gives you, for each deleted content items (those have all their latest and published flags to zero on all their content item version records), the maximum version number, i.e. the latest version of each deleted content item.

Updating column based on three tables

I know it's very unprofessional, but it's our business system so I can't change it.
I have three tables: t_posList, t_url, t_type. The table t_posList has a column named URL which is also stored in the table t_url (the ID of the table t_url is not saved in t_posList so I have to find it like posList.Url = t_url.Url).
The column t_posList.status of every data row should be updated to 'non-customer' (it will be a status id but lets keep it simple) if: the ID of t_url can NOT be found in t_type.url_id.
So the query has like two steps: first I have to get all of the data rows where t_posList.Url = t_url.Url. After this I have to check which ID's of the found t_url rows can NOT be found in t_type.url_id.
I really hope you know what I mean. Because our system is very unprofessional and my SQL knowledge is not that good I'm not able to make this query.
EDIT: I tried this:
UPDATE t_poslist SET status = (
SELECT 'non-customer'
FROM t_url, t_type
WHERE url in
(select url from t_url
LEFT JOIN t_type ON t_url.ID = t_type.url_id
WHERE t_type.url_id is null)
)
What about this?
UPDATE p
SET status = 'non-customer'
FROM t_poslist p
INNER JOIN t_url u ON u.url = p.url
WHERE NOT EXISTS
(
SELECT * FROM t_type t WHERE t.url_id = u.ID
)

How to get the table name from a field in a join query with MSSQL? (mysql_field_table equivalent)

I'm doing a query manager in Delphi using ADO, I need to know all fields that will be returned by a query, does no matter how complex and how much joins they will have. I want to call a function, that return to me, all fields that will be returned in a specific query, and fields information, like table what is this field from.
In mysql with php, I have the command mysql_field_table, in this command I pass the result object and the field index and this command return the table name for me.
Well, that is my dream, get the table name from a field index in a query like:
SELECT * FROM TableOne Left Join Table2 ON Table2.MasterField = Table1.KeyField
You could use a TADODataSet to fetch the Recordset, iterate the Fields collection, and get the tables/fields names like this:
for I := 0 to ADODataSet1.Recordset.Fields.Count - 1 do
begin
TableName := ADODataSet1.Recordset.Fields[i].Properties['BASETABLENAME'].Value;
FieldName := ADODataSet1.Recordset.Fields[i].Properties['BASECOLUMNNAME'].Value;
end;

Resources