how can write this query in django ORM - django-models

how to write in django ORM query select all rows(id) which id not userreg
select * from userreg where user_id not in (select user_id from emp_details)

Something like this:
from django.db.models import Q
emp_id_list = Emp_details.objects.values('user_id')
res_list = Userreg.objects.filter(~Q(user_id__in = emp_id_list))

Related

Combine multiple SQL statements into one stored procedure

Okay from these two tables:
SELECT *
FROM Sessions
JOIN Sessions ON Sessions.ID = Sessions.SessionID
I need to count how many seats are taken (counting how many of each sessionID exist)
SELECT DISTINCT
Sessions.SessionID,
COUNT(*) OVER (PARTITION BY SessionID) AS Sess
FROM
Sessions
WHERE
UserID = #UserId
And then if the count Sess is less (an int column in table), select only those sessions from my join (below code is not correct):
SELECT *
FROM Sessions
WHERE UserId = #UserId
How do I combine all of these statements into one stored procedure?
Each select statement works on its own, but I don't know how to combine this into one solution.
WITH EligibleSessions As (
SELECT s.ID
FROM Sessions s
JOIN RegistrantSessions rs ON s.ID = rd.SessionID
WHERE rs.EventID = #EventID
GROUP BY s.ID, s.SeatLimit
HAVING COUNT(rs.*) < s.SeatLimit
)
SELECT s.*
FROM Sessions
INNER JOIN EligibleSessions es on es.ID = s.ID
WHERE s.EventId = #EventId
AND s.SessionTime = #SessionTime
AND s.SessionType = #SessionType
AND s.Active = #SessionActive
There seems like an extra layer of nesting here, but I didn't want to have to include every field in the Sessions table in the GROUP BY.
You may need to repeat some of the WHERE conditions in the CTE. It's also weird to me for the EventID field to repeated in both Sessions and RegistrantSessions. Seems like an indication something is not normalized properly.
If I understand your table structure correctly, we could join a the count query as subselect too:
SELECT *
FROM Sessions
JOIN (
SELECT DISTINCT RegistrantSessions.SessionID
,COUNT(*) OVER (PARTITION BY SessionID) AS SeatCount
FROM RegistrantSessions
JOIN RegistrantSessions ON Sessions.ID = RegistrantSessions.SessionID
WHERE EventID = #EventId
) AS regCounts ON regCounts ON Sessions.ID = regCounts.SessionID
WHERE Sessions.SeatLimit < regCounts.SeatCount
AND EventId = #EventId
AND SessionTime = #SessionTime
AND SessionType = #SessionType
AND Active = #SessionActive

Check if record exists with Dapper ORM

What is the simplest way to check if record exists using the Dapper ORM?
Do I really need to define POCO objects for a query where I only want to check if a record exists?
int id = ...
var exists = conn.ExecuteScalar<bool>("select count(1) from Table where Id=#id", new {id});
should work...
I think this may have a tad less overhead as there's no function call or data type conversions:
int id = ...
var exists = connection.Query<object>(
"SELECT 1 WHERE EXISTS (SELECT 1 FROM MyTable WHERE ID = #id)", new { id })
.Any();
const string sql = "SELECT CAST(CASE WHEN EXISTS (SELECT 1 FROM MyTable WHERE Id = #Id) THEN 1 ELSE 0 END as BIT)";
bool exists = db.ExecuteScalar<bool>(sql, new { Id = 123 });
You can have your query to return a bool:
[Test]
public void TestExists()
{
var sql = #"with data as
(
select 1 as 'Id'
)
select CASE WHEN EXISTS (SELECT Id FROM data WHERE Id = 1)
THEN 1
ELSE 0
END AS result
from data ";
var result = _connection.Query<bool>(sql).FirstOrDefault();
Assert.That(result, Is.True);
}
conn.QuerySingleOrDefault<bool>("select top 1 1 from table where id=#id", new { id});
Another option that will run with duplicate records, i.e. not querying the id of the table
bool exists = connection.ExecuteScalar<int>(
"select count(1) from Table where notanId=#value", new { value = val})
> 0;
If you need to do this sort of query against a non-unique field you can use HAVING to handle counts greater than 1.
SELECT 1
FROM Table
WHERE Col=#val
HAVING COUNT(1) > 0
imho SELECT TOP(1) is better than SELECT COUNT(1)
bool exists = connection.Query<ValueTuple<long>>(
"SELECT top(1) Id FROM MYTABLE WHERE MYTABLE.Id=#Id",
new {Id}).Any());
The ValueTuple<long> is value type . Query<object> map to reference type and causes boxing .

Postgres Proper usage of Group by in a Inner Join Statement

EDIT I updated my question with a SQL Fiddle Sample http://sqlfiddle.com/#!15/8d88b/1
I'm currently making a report from a database records but I don't know how my query should look like, first of all I have 2 tables. Application Forms, and a table for Login Hours of each user
forms
->id
->agent_id
->SomeInfo
->created_at
loginhours
->id
->user_id
->loginhours (decimal)
->created_at
And I have report with the following columns
UserID, TotalLoginHours, TotalApplication, Application Per Hour (aph), Revenue Per Hour (rph)
So right now I have this query
SELECT a.agent_id, SUM(b.loginhours) as TotalLoginHours, COUNT(a.id) as TotalApplication, SUM(b.loginhours) / COUNT(a.id) as ApplicationPerHour, (SUM(b.loginhours) / COUNT(a.id)) * 1.75 as RPH
FROM forms a
INNER JOIN loginhours b ON a.agent_id = b.user_id WHERE a.created_at = '2015-07-17'
GROUP BY a.agent_id
Note that user_id and agent_id is the same.
I want to get the result based on the date selected, example 2015-07-17 I got results but my problem is the loginhours is being SUM based on the number of application for each user. So for example the user1 has 2 records on forms table and his loginhours from 2015-07-17 is 2 then in my result the loginhours becomes 4 which is wrong, I think it is on my GROUP BY statement. Can you help me how to properly query this?
Thanks
I don't know if this is a good practice but somehow I figured it out with
SELECT a.agent_id
,(SELECT SUM(loginhours)
FROM loginhours
WHERE user_id = a.agent_id
AND created_at = '2015-07-17'
GROUP BY created_at) as TotalLoginHours
,COUNT(a.id) as TotalApplication
,(SELECT SUM(loginhours)
FROM loginhours
WHERE user_id = a.agent_id
AND created_at = '2015-07-17'
GROUP BY created_at) / COUNT(a.id) as ApplicationPerHour
,((SELECT SUM(loginhours)
FROM loginhours
WHERE user_id = a.agent_id
AND created_at = '2015-07-17'
GROUP BY created_at) / COUNT(a.id)) * 1.75 as RPH
FROM forms a
INNER JOIN loginhours b
ON a.agent_id = b.user_id
WHERE a.created_at = '2015-07-17'
GROUP BY a.agent_id;
SELECT user_id, loginhours, applications,
loginhours/applications as applications_per_hour,
loginhours/applications * 1.75 as rph
FROM
(
SELECT user_id, SUM(loginhours) as loginhours
FROM loginhours
WHERE created_at = '2015-07-17'
GROUP BY user_id
)hours
JOIN
(
SELECT agent_id, COUNT(DISTINCT id) as applications
FROM forms
WHERE created_at = '2015-07-17'
GROUP BY agent_id
)applications
ON hours.user_id = applications.agent_id

SQL not exists returning query values

I'm having some trouble with a query to check differences between 2 identical tables with different rows.
This is the query
SELECT *
FROM [PROD01].[myDefDB].[forward].[fv] as DB01
WHERE TargetDate = '20150429' and
NOT EXISTS (SELECT *
FROM [PROD02].[myDefDB].[forward].[fv] as DB02
WHERE DB02.TargetDate = '20150429' and
DB02.Id_Fw = DB01.Id_Fw and
DB02.Id_Bl = DB01.Id_Bl and
DB02.Id_Pt = DB01.Id_Pt and
DB02.TargetDate = DB01.TargetDate and
DB02.StartDate = DB01.EndDate and
DB02.EndDate = DB01.EndDate and
DB02.[Version] = DB01.[Version]
)
Consider that [PROD02].[myDefDB].[forward].[fv] is a subset of [PROD01].[myDefDB].[forward].[fv], that performing a SELECT count(*) on both tables for the TargetDate = '20150429' returns me 2367 and 4103, so I expect to get 1736 from that query but I get more than 2000.
I considered all PKs in the WHERE clause. What am I missing?
You can use EXCEPT like this.
SELECT Id_Fw,Id_Bland,Id_Pt,TargetDate,StartDate,EndDate,[Version]
FROM [PROD01].[myDefDB].[forward].[fv] as DB01
WHERE TargetDate = '20150429'
EXCEPT
SELECT Id_Fw,Id_Bl,Id_Pt,TargetDate,StartDate,EndDate,[Version]
FROM [PROD02].[myDefDB].[forward].[fv] as DB02
WHERE TargetDate = '20150429'
This will get you all the rows in PROD01 which are not in PROD02

SQL Server - IN clause with multiple fields

Is it possible to include in a IN clause multiple fields? Something like the following:
select * from user
where code, userType in ( select code, userType from userType )
I'm using ms sql server 2008
I know this can be achieved with joins and exists, I just wanted to know if it could just be done with the IN clause.
Not the way you have posted. You can only return a single field or type for IN to work.
From MSDN (IN):
test_expression [ NOT ] IN
( subquery | expression [ ,...n ]
)
subquery - Is a subquery that has a result set of one column.
This column must have the same data type as test_expression.
expression[ ,... n ] - Is a list of expressions to test for a match.
All expressions must be of the same type as
test_expression.
Instead of IN, you could use a JOIN using the two fields:
SELECT U.*
FROM user U
INNER JOIN userType UT
ON U.code = UT.code
AND U.userType = UT.userType
You could use a form like this:
select * from user u
where exists (select 1 from userType ut
where u.code = ut.code
and u.userType = ut.userType)
Only with something horrific, like
select * from user
where (code + userType) in ( select code + userType from userType )
Then you have to manage nulls and concatenating numbers rather than adding them, and casting, and a code of 12 and a usertype of 3 vs a code of 1 and a usertype of 23, and...
..which means you start heading into perhaps something like:
--if your SQLS supports CONCAT
select * from user
where CONCAT(code, CHAR(9), userType) in ( select CONCAT(code, CHAR(9), userType) from ... )
--if no concat
select * from user
where COALESCE(code, 'no code') + CHAR(9) + userType in (
select COALESCE(code, 'no code') + CHAR(9) + userType from ...
)
CONCAT will do a string concatenation of most things, and won't zip the whole output to NULL if one element is NULL. If you don't have CONCAT then you'll string concat using + but anything that might be null will need a COALESCE/ISNULL around it.. And in either case you'll need something like CHAR(9) (a tab) between the fields to prevent them mixing.. The thing between the fields should be southing that is not naturally present in the data..
Tis a shame SQLS doesn't support this, that Oracle does:
where (code, userType) in ( select code, userType from userType )
but it's probably not worth switching DB for; I'd use EXISTS or a JOIN to achieve a multi column filter
So there ya go: a solution that doesn't use joins or exists.. and a bunch of reasons why you shouldn't use it ;)
How about this instead:
SELECT user.* FROM user JOIN userType on user.code = userType.code AND user.userType = userType.userType
You can either use joins
SELECT * FROM user U
INNER JOIN userType UT on U.code = UT.code
AND U.userType = UT.userType
I had to do something very similar but EXISTS didn't work in my situation. Here is what worked for me:
UPDATE tempFinalTbl
SET BillStatus = 'Non-Compliant'
WHERE ENTCustomerNo IN ( SELECT DISTINCT CustNmbr
FROM tempDetailTbl dtl
WHERE dtl.[Billing Status] = 'NEEDS FURTHER REVIEW'
AND dtl.CustNmbr = ENTCustomerNo
AND dtl.[Service] = [Service])
AND [Service] IN ( SELECT DISTINCT [Service]
FROM tempDetailTbl dtl
WHERE dtl.[Billing Status] = 'NEEDS FURTHER REVIEW'
AND dtl.CustNmbr = ENTCustomerNo
AND dtl.[Service] = [Service])
EDIT: Now that I look, this is very close to #v1v3kn's answer
I don't think that query is quite portable,it would be safer to use something like
select * from user
where code in ( select code from userType ) and userType in (select userType from userType)
select * from user
where (code, userType) in ( select code, userType from userType );

Resources