How to make this select in SubSonic using SqlQuery ?
SELECT * FROM [dbo].[Tablexxx]
Join Tableyyy on Tablexxx.fieldZZZ = Tableyyy.fieldZZZ
WHERE Tablexxx.fieldxxx = 1 AND
(Tablexxx.fieldyyy = 'S' or Tablexxx.fieldyyy = 'T')
Thanks any help.
Valmir
var query = DB.Select().From<Table1>()
.InnerJoin<Table2>()
// Where() takes a ColumnSchema type
.Where(Table1.FieldXColumn).IsEqualTo(1)
// AndExpression only takes strings, so use the column struct
.AndExpression(Table1.Columns.FieldY).IsEqualTo("S")
.Or(Table1.FieldYColumn).IsEqualTo("T")
.ExecuteAsCollection();
Related
I want to join 2 tables where user.id = photo.userId but the problem here is that the userId on photo table is varchar and that can't change. So I did a queryBuilder to join and the problem is here:
....
.where(user.id = photo.userId)
....
this query throw an error: operator does not exists: uuid = character varying
Is there any way to make this work?
Note: My project is a NestJS API, using TypeORM and Postgresql.
EDIT
I already have the Photo result and use it on a subQuery:
query = query
.where(qb => {
const subQuery = qb.subQuery()
.select('user.id')
.from(User, 'user')
.where('user.id = photo.userId)
.getQuery();
return 'EXISTS' + subQuery;
});
https://www.postgresqltutorial.com/postgresql-cast/
where (user.id::VARCHAR = photo.userId)
Thank you for the help, finally the best solution I found was to create a postgres function as indicated here and then call it in the code like this:
query = query
.where(qb => {
const subQuery = qb.subQuery()
.select('user.id')
.from(User, 'user')
.where('user.id = uuid_or_null(photo.userId)) // here
.getQuery();
return 'EXISTS' + subQuery;
});
First off the conversion of 'I' to "i" (upper to lower) in userId is exactly what would be expected, as identifiers are all lower cased unless double quoted. Avoid that if possible as when used you must double quote every time the identifier is used.
Secondly the type uuid has some strange and unexpected formatting rules. You can compare a string::uuid to a uuid as expected, but uuid::text may not compare to a srting. As uuid::text will format as hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh (where h is a hexdigit). The dashes are often removed if storing as a a string. So reverse the typical order; cast the string as uuid. See the following example:
create table id_uuid (id uuid, col1 text);
create table id_str (id text, col1 text
insert into id_uuid(id, col1) values(gen_random_uuid(),'Id defined as uuid');
insert into id_str (id, col1)
select replace(id::text,'-',''),'Id defined as string'
from id_uuid;
select * from id_uuid;
select * from id_str;
select *
from id_uuid u
join id_str s
on (u.id::text = s.id);
select *
from id_uuid u
join id_str s
on (u.id = s.id::uuid);
If I query SqLite table using single key, I can use the following code for parametrization:
contact_phones_list = ['+123456789', '+987654321']
q = "select * from {} WHERE user_phone in ({})".format(
my_table_name,
', '.join('?' for _ in contact_phones_list)
)
res = self.cursor.execute(q, contact_phones_list).fetchall()
Now I want to query for key pairs for which I have values:
keys = ['user_phone', 'contact_phone']
values = [('+1234567', '+1000000'), ('+987654321', '+1200000')]
q = "select contact_phone, is_main, aliases from {} WHERE ({}) in ({})".format(
my_table_name,
', '.join(keys),
', '.join('(?, ?)' for _ in values)
)
res = self.cursor.execute(q, values).fetchall()
I'm getting error "row value misused". I tried many combinations with sublist instead of tuple, single "?", etc.
How can I create parametrization in this case?
EDIT: adding "VALUES" keyword and flattening list works:
keys = ['user_phone', 'contact_phone']
values = [('+1234567', '+1000000'), ('+987654321', '+1200000')]
values_q = []
for v in values:
values_q += [v[0], v[1]]
q = "select * from my_table_name WHERE ({}) IN (VALUES {})".format(
', '.join(keys),
', '.join('(?, ?)' for _ in values)
)
res = cursor.execute(q, values_q).fetchall()
Is this a workaround or only acceptable solution?
From the documentation:
For a row-value IN operator, the left-hand side (hereafter "LHS") can be either a parenthesized list of values or a subquery with multiple columns. But the right-hand side (hereafter "RHS") must be a subquery expression.
You're building up something that looks like (?,?) IN ((?,?), (?,?)), which doesn't meet that requirement. The syntax (?,?) IN (VALUES (?,?), (?,?)) works, though.
Also, I think you might have to flatten out that list of tuples you pass to the prepared statement, but somebody more knowledgeable about python would have to say for sure.
way to map the following to a Dictionary??
Sql sql = new Sql()
.Append("SELECT Count(*) ")
.Append("FROM Custumers")
.Append("WHERE CustomerId = #0", Id)
var result = database.Fetch<Dictionary<int,DateTime>>(sql);
I cannot use List as DateTime is also thr.
Petapoco always return a List<T>, but you can convert the List to a Dictionary afterwards:
var result = database
.Fetch<Pair<int,DateTime>>(sql)
.ToDictionary(i => i.ID, i => i.Date);
With NPoco you can write this: it will use the first 2 columns
var result = database.Dictionary<int, DateTime>(sql);
or use what #Eduardo said.
Can I do something like this on JPQL?
SELECT NEW com.MyDTO(p.a, p.b, q.c, q.d)
FROM
(SELECT r.* FROM MyDTO1 r ) p
LEFT OUTER JOIN
(SELECT s.* FROM MyDTO2 s ) q
ON p.x = q.y
or similar?
(Above query has mixed with native and JPQL, so don't misunderstand)
I'm having a problem with this part I think.
FROM
(SELECT r.* FROM MyDTO1 r ) p
When I'm trying to execute I'm getting this error.
Exception Description: Syntax error parsing the query [.....], unexpected token [(]
Thank you!
No, you can't. Quote from the documentation:
Note that HQL subqueries can occur only in the select or where
clauses.
Yes you can!
You have to use native queries. Here is an example:
emf = Persistence.createEntityManagerFactory("TEST")
EntityManager em = emf.createEntityManager();
String queryString = "SELECT ID FROM ( SELECT * FROM ADDRESS WHERE ID < 0)";
Query query = em.createNativeQuery(queryString);
List<BigDecimal> result = query.getResultList();
Here is a SQL Query I want to convert to EF4.3
command = database.GetSqlStringCommand(#"
select
H.AUTHENTICATION_ID,
USERNAME,
PERMISSIONS,
ORGANIZATION_IDENTIFIER,
O.ORGANIZATION_ID
from
AUTHENTICATION H
left join [AUTHORIZATION] T on H.AUTHENTICATION_ID=T.AUTHENTICATION_ID
join ORGANIZATION O on O.ORGANIZATION_ID = T.ORGANIZATION_ID
order by H.AUTHENTICATION_ID");
Here is the best LINQ I could come up with:
var query = from h in context.Authentications
join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId
join o in context.Organizations on t.Organizations.OrganizationId equals o.OrganizationId
orderby
h.AuthenticationId
select new
{ AUTHENTICATION_ID = (Int16?)h.AuthenticationId,
h.Username,
t.Permissions,
o.OrganizationIdentifier,
OrganizationID = (Int16?)o.OrganizationId
};
I know i need to merge my first join (between Authorizations & Authentications) into, lets say x and apply DefaultIfEmpty but can't make out the syntax.
EDIT: Image for clarification:
Any help will be highly appreciated. Regards.
The basic syntax for a "left join" in Linq is like this:
from x in table1
join y in table2 on x.id equals y.id into jointable
from z in jointable.DefaultIfEmpty()
select new
{
x.Field1,
x.Field2,
x.Field3,
Field4 = z == null ? 0 : z.Field4
};
In your case, I'm a little confused because the entity relations you seem to be using in your Linq don't match the ones implied by your SQL; are the relationships here zero-or-one, zero-or-many, one-to-one, etc? Specifically, you're doing this:
from h in context.Authentications
join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId
but your SQL implies that "Authentication" is the parent here with zero-or-more "Authorization" children, not the other way around, which would be more like:
from h in context.Authentications
from t in h.Authorizations.DefaultIfEmpty()
If you can give us a better idea of the data model and what data you expect to get out of it we can more easily explain how that query would look in Linq. Assuming that your relationships match what is implied by the SQL, you should be able to get what you want using the following Linq queries:
var query = from h in context.Authentications
from t in h.Authorizations.DefaultIfEmpty()
select new
{
h.AuthenticationId,
h.Username,
Permissions = t == null ? null : t.Permissions,
Organizations = t == null ? new EntitySet<Organization>() : t.Organizations
};
var query2 = from x in query
from o in x.organizations.DefaultIfEmpty()
select new
{
AUTHENTICATION_ID = (short?)x.AuthenticationId,
x.Username,
x.Permissions,
OrganizationIdentifier = o == null ? null : o.OrganizationIdentifier,
OrganizationID = o == null ? (short?)null : o.OrganizationID
};
Given the foreign keys that exist in the question diagram, how about something like this?
var query = from a in context.Authentications
select new
{
a.AuthenticationID,
a.Username,
a.Authorisations.Permissions ?? false,
a.Authorisations.Organisations.OrganisationIdentifier ?? 0
a.Authorisations.Organisations.OrganisationID ?? 0
};
I went ahead and moved the entire query to a Stored Procedure on the database. This solves the problem by avoiding LINQ and ObjectBuilder in the first place.