SOQL Count with multiple Where clauses - salesforce

I am trying to count all the results that match multiple Where conditions in Salesforce. All these Where conditions exist under the same object that I am selecting from. It seems like it should be a simply query but my SQL and SOQL experience is limited.
Here's my code right now:
SELECT count() FROM Account
WHERE Success__c='yes'
AND Active__c='true'
AND Days__c>'30'
AND Days__c<'37'

It'd be useful to see the actual error message, but at a guess, you have quotes around things that shouldn't have them, e.g. you want
SELECT count() FROM Account
WHERE Success__c = 'yes'
AND Active__c = true
AND Days__c > 30
AND Days__c < 37
Also there are tools like SoqlX, the Force.com IDE and Workbench that'll let you run queries, so if Geckoboard is hiding the actual error message, you can work through getting a good query in one of these tools first.

Related

How to retrieve data from LedgerJournalTrans table (based on relations and joins) for voucher transaction form in D365FinOp?

Basically I have a client request to implement:
Need to show data from the following fields : PaymMode, BankChequeNum, LedgerDimensionName, JournalNum from ledgerJournalTrans table on the LedgerTransVoucher form but have been unable to do so have tried nearly all of the possible queries that I could think of but none of them are working the way I expect them to: either the query is doing a cartesian product and duplicating the records or it is displaying no data in those fields.
Below is the query that I have recently tried:
public display MH_AccountTitle displayBeneficiaryName(GeneralJournalAccountEntry _accountEntry)
{
select SubledgerVoucher, AccountingDate from journalEntry
where journalEntry.RecId == _accountEntry.GeneralJournalEntry
join Voucher, MH_AccountTitle, RecId, AmountCurDebit, AmountCurCredit, TransDate from LedgerTrans
where LedgerTrans.Voucher == journalEntry.SubledgerVoucher
&& LedgerTrans.TransDate == journalEntry.AccountingDate
&& LedgerTrans.PaymReference == _accountEntry.PaymentReference
&& (abs(_accountEntry.TransactionCurrencyAmount) == LedgerTrans.AmountCurDebit
|| abs(_accountEntry.TransactionCurrencyAmount) == LedgerTrans.AmountCurCredit);
return ledgerTrans.MH_AccountTitle;
}
I know this query is logically incorrect because joins can't be applied on the basis of date and amount but this was suggested by a senior of mine after all else failed, and it did work, records were returned correctly but it failed where there were multiple transactions with same TransactionCurrencyAmount,TransDate and voucher
join with PaymentReference also failed where the method of payment was not Check and hence there was no BankChequeNum/Payment reference resulting in the same problem
Anyone who has any idea of what could be work around for this?
Note:
work has been done on a custom form of LedgerTransVoucher
display method approach was used because simply applying joins on the form's data source didn't work
Also code has been written on form's datasource GeneralJournalAccountEntry
What I usually do to debug these kinds of issues is get the query string that X++ creates when using inline SQL. Often there is something that X++ translates into SQL that is not expected.
Secondly, I always write my queries in SSMS first to avoid having unwanted results because of the X++ translation to SQL query.
You can get the query string by either making a query object and using the .ToString() method or you can take a trace and use Traceparser to view the query that was sent to the SQL Server.
I am thinking the abs() functions will be the issue here.

Performance issue with django exclude

I have a Django 1.8 application, and I am using an MsSQL database, with pyodbc as the db backend (using "django-pyodbc-azure" module).
I have the following models:
class Branch(models.Model):
name = models.CharField(max_length=30)
startTime = models.DateTimeField()
class Device(models.Model):
uid = models.CharField(max_length=100, primary_key=True)
type = models.CharField(max_length=20)
firstSeen = models.DateTimeField()
lastSeen = models.DateTimeField()
class Session(models.Model):
device = models.ForeignKey(Device)
branch = models.ForeignKey(Branch)
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
I need to query the session model, and I want to exclude some records with specific device values. So I issue the following query:
sessionCount = Session.objects.filter(branch=branch)
.exclude(device__in=badDevices)
.filter(end__gte=F('start')+timedelta(minutes=30)).count()
badDevices is a pre-filled list of device ids with around 60 items.
badDevices = ['id-1', 'id-2', ...]
This query takes around 1.5 seconds to complete. If I remove the exclude from the query, it takes around 250 miliseconds.
I printed the generated sql for this queryset, and tried it in my database client. There, both versions executed in around 250 miliseconds.
This is the generated SQL:
SELECT [session].[id], [session].[device_id], [session].[branch_id], [session].[start], [session].[end]
FROM [session]
WHERE ([session].[branch_id] = my-branch-id AND
NOT ([session].[device_id] IN ('id-1', 'id-2', 'id-3',...)) AND
DATEPART(dw, [session].[start]) = 1
AND [session].[end] IS NOT NULL AND
[session].[end] >= ((DATEADD(second, 600, CAST([session].[start] AS datetime)))))
So, using the exclude in database level doesn't seem to be affecting the query performance, but in django, the query runs 6 times slower if I add the exclude part. What could be causing this?
The general issue seems to be that django is doing some extra work to prepare the exclude clause. After that step and by the time the SQL has been generated and sent to the database, there isn't anything interesting happening on the django side that could cause such a significant delay.
In your case, one thing that might be causing this is some kind of pre-processing of badDevices. If, for instance, badDevices is a QuerySet then django might be executing the badDevices query just to prepare the actual query's SQL. Possibly something similar might be happening in the case where device has a non-default primary key.
The other thing might delay the SQL preparation is of course django-pyodbc-azure. Maybe it's doing something strange while compiling the query and it becomes a bottleneck.
This is all wild speculation though, so if you're still having this issue then post the Device and Branch models as well, the exact content of badDevices and the SQL generated from the queries. Then maybe some scenarios can be at least eliminated.
EDIT: I think it must be the Device.uid field. Possibly django or pyodbc is getting confused by the non-default primary key and is fetching all the devices while generating the query. Try two things:
Replace device__in with device_id__in, device__pk__in and device__uid__in and check each one again. Maybe a more explicit query will be easier for django to translate into SQL. You can even try replacing branch with branch_id, just in case.
If the above doesn't work, try replacing the exclude expression with a raw SQL where clause:
# add quotes (because of the hyphens) & join
badDevicesIdString = ", ".join(["'%s'" % id for id in badDevices])
# Replaces .exclude()
... .extra(where=['device_id NOT IN (%s)' % badDevicesIdString])
If neither works, then most likely the problem is with the whole query and not just exclude. There are some more options in that case but try the above first and I will update my answer later if necessary.
Just want to share a similar problem that I had with MySQL and exclude clauses performance and how it was fixed.
When running the exclude clause, the list with the "in" lookup was actually a Queryset that I got using values_list method. Checking the exclude query executed by MySQL, the "in" objects were not values but actually another query. This behavior was impacting performance on specific large queries.
To fix that, instead of passing the queryset, I flat it out in a python list of values. By doing that, each value is passed as an argument inside the in lookup and the performance was really improved.

Adding Geo-IP data to Query in Access SQL

Ok this sounds like a problem that someone else should have solved already, but I can't find any help on it, just that their should be a better way of doing it than using an unequal join.
I have a log file of session info with a Source IP, and I am trying to create a query, that actually runs, to combine the Log file with Geo-IP data to tell the DB where users are connecting from. my first attempt came to this:-
SELECT coco, region, city
FROM GT_Geo_IP
WHERE (IP_Start <= [IntIP] AND IP_End >=[IntIP])
ORDER BY IP_Start;
it seemed to run quite quick and returns the correct record for a given IP. but when I tried to combine it with the log data, like this:-
SELECT T.IP,G.coco,G.region, g.city
FROM GT_Geo_IP as G, Log_Table as T
WHERE G.IP_Start <= T.IntIP AND G.IP_End >= T.IntIP
ORDER BY T.IP;
it locks access for over 45 mins (pegging one of my cpu cores) before i finally decide i need some CPU back or i should actually have a go at something else. From hunting around and this is actually slower than i realize, I found this article and indexed both IP_Start and IP_End to optimize the Search, and based on it came up with this:-
SELECT TOP 1 coco, region, city
FROM GT_Geo_IP
WHERE G.IP_Start >= [IntIP]
ORDER BY G.IP_Start;
But with my SQL skills i cant work out how to combine it with my log data.
Basically the question is how do i use the better method with my log data to get the required result? or is there a better way to do it?
The GeoIP data is from IP2Location's LITE-DB3
I have thought about nested queries, but i couldn't work out how to construct it, I thought about using VBA, but i'm not sure it will be any quicker
#EnviableOne
Please try this SQL statement.
SELECT
L.IP,
(
SELECT TOP 1
CONCAT(coco, ', ', region, ', ', city)
FROM
GT_Geo_IP
WHERE
IP_Start >= L.intIP ORDER BY IP_Start
) AS Location
FROM
Log_Table AS L;

SOQL Query to fetch more than 2000 records

How to fetch more than 2000 records through SOQL ....
Is there something query more ?
call queryMore with the queryLocator provided in the first set of results, keep calling it with the next queryLocator until the done flag is true. See the Web Services API docs for more info.
You can actually do this manually as well if you order by id and then query again with "where id > : idPrevious". If you try this just as I've typed it you'll hit a problem however, you can't use > and < with id fields. There is a simple work around for this though, just create a text type formula field which takes it's value from the id field. Then you can use that field in the query with no problems.
Of course if you're just looking to process loads of data then you might really be looking for Batch Apex.

SQL Query Notifications and GetDate()

I am currently working on a query that is registered for Query Notifications. In accordance w/ the rules of Notification Serivces, I can only use Deterministic functions in my queries set up for subscription. However, GetDate() (and almost any other means that I can think of) are non-deterministic. Whenever I pull my data, I would like to be able to limit the result set to only relevant records, which is determined by the current day.
Does anyone know of a work around that I could use that would allow me to use the current date to filter my results but not invalidate the query for query notifications?
Example Code:
SELECT fcDate as RecordDate, fcYear as FiscalYear, fcPeriod as FiscalPeriod, fcFiscalWeek as FiscalWeek, fcIsPeriodEndDate as IsPeriodEnd, fcPeriodWeek as WeekOfPeriod
FROM dbo.bFiscalCalendar
WHERE fcDate >= GetDate() -- This line invalidates the query for notification...
Other thoughts:
We have an application controls table in our database that we use to store application level settings. I had thought to write a small script that keeps a record up to date w/ teh current smalldatetime. However, my join to this table is failing for notificaiton as well and I am not sure why. I surmise that it has something to do w/ me specifitying a text type (the column name), which is frustrating.
Example Code 2:
SELECT fcDate as RecordDate, fcYear as FiscalYear, fcPeriod as FiscalPeriod, fcFiscalWeek as FiscalWeek, fcIsPeriodEndDate as IsPeriodEnd, fcPeriodWeek as WeekOfPeriod
FROM dbo.bFiscalCalendar
INNER JOIN dbo.xApplicationControls ON fcDate >= acValue AND acName = N'Cache_CurrentDate'
Does anyone have any suggestions?
EDIT: Here is a link on MSDN that gives the rules for Notification Services
As it turns out, I figured out the solution. Basically, I was invalidating my query attempts because I was casting a value as a DateTime which marks it as Non-Deterministic. Even though you don't specifically call out a cast but do something akin to:
RecordDate = 'date_string_value'
You still end up w/ a Date Cast. Hopefully this will help out someone else who hits this issue.
This link helped me quite a bit.
http://msdn.microsoft.com/en-us/library/ms178091.aspx
A good way to bypass this is simply to create a view that just says "SELECT GetDate() AS Now", then use the view in your query.
EDIT : I see nothing about not using user-defined functions (which is what I've used the 'view today' bit in). So can you use a UDF in the query that points at the view?

Resources