How to resolve a Left Join sub-query error? - sql

In MS-Access I'm trying to join three tables. The third table is created from a sub-query designed to aggregate dates because I don't want multiple records per day when aligned with the first table.
When I entered the left join sub-query, I got this error:
The field is too small to accept the amount of data you attempted to
add. Try inserting or pasting less data.
I've run the sub-query separately and it returns about 19,000 records. Which is quite smaller than the actual table. If I use the actual table, the query works just fine, but it includes the duplicate records when there is more than one entry per day on the third table.
SELECT
SUM([ACD Calls]),
(SUM([Avg ACD Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
(SUM([Avg ACW Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
((SUM([Hold Time])/SUM([ACD Calls])))/86400,
((SUM([Avg ACD Time]*[ACD Calls])
+ SUM([Avg ACW Time]*[ACD Calls]))/SUM([ACD Calls]))/86400,
SUM([Time Adhering])/SUM([Total Time Scheduled]),
SUM([SS])/SUM([SO])
FROM
(
(
[GroupSumDaily]
LEFT JOIN Adherence_WKLY ON (GroupSumDaily.[Day] = Adherence_WKLY.[Day])
AND (GroupSumDaily.Agent = Adherence_WKLY.Agent)
)
LEFT JOIN
(
SELECT Evaluation_List.[Agent],
Evaluation_List.Recording_Date,
SUM(Evaluation_List.[Score]) as SS,
SUM(Evaluation_List.[Out of]) as SO
From Evaluation_List
Group By Evaluation_List.[Recording_Date],
Evaluation_list.[Agent]
)
as Evals ON (GroupSumDaily.[Day] = Evals.[Recording_Date])
AND (GroupSumDaily.Agent = Evals.Agent)
)
WHERE
(
[GroupSumDaily].[Agent] = "LastName FirstName"
AND Month([GroupSumDaily].[Day]) =1
AND Year([GroupSumDaily].[Day]) =2018
AND [GroupSumDaily].[Day] > #2/23/2015#
)

It looks like you don't have a "main" table to query from.
I'd try removing the first two open brackets after the FROM statement (and their equivalent closing brackets.)
If that doesn't fix it, try moving the whole sub-query into a separate query and selecting from the results...

It turns out the subquery fields are automatically limited to 50 characters and this was the root of the problem. When I limited the return to LEFT([Agent], 50), the error disappeared. Is there a way to set character length is a subquery field?
The other odd things is, none of my fields were actually over 50 characters... when I ran Select [Agent] Where LEN([Agent]) >= 50, it returned only 1 records, and it was the "NEW" blank record from the bottom. I confirmed that it completely blank, with no spaces or tabs. Very confusing.

Related

MS Access Append Query - Field not working

I have an append query which has an Excel Sheet as a datasource. Today the underlying data of one of the fields was changed from String to Long. In my query table I had this particular field calculated as:
MSCI: Left([bp_msci_ic_key];2)
in order to compensate for the change in underlying data format I changed it to...
MSCI: Left(*Str*([bp_msci_ic_key]);2)
Unfortunately, the query produces #ERROR with this... why does this approach not work?
Here the syntax of the entire SQL statement:
INSERT INTO tbl_Position(
MoPo_ID,
AssetClass_Sub_ID,
VALOR,
ISIN,
[Currency],
Position_Name,
Weight,
Rating,
Asset_Country,
Issuer_Country,
Position_Duration,
Position_YieldToMaturity,
MSCI_Code,
PosValue)
SELECT
qry_Position_Load_step1.MoPo_BM_ID,
qry_Position_Load_step1.AssetClass_Sub_ID,
qry_Position_Load_step1.VALOR,
qry_Position_Load_step1.ISIN,
IIf([qry_Position_load_step1]![ccy] Is Null And Left([qry_Position_load_step1]![classsub],2)="M_", Mid([qry_Position_load_step1]![classsub],3,Len([qry_Position_load_step1]![classsub])-1),[qry_Position_load_step1]![CCY]) AS CCY,
qry_Position_Load_step1.NAME_SHORT,
qry_Position_Load_step1.Val,
tbl_MopoRohdaten.rating_clir,
tbl_MopoRohdaten.ass_domi_country,
tbl_MopoRohdaten.iss_domi_country,
tbl_MopoRohdaten.pos_dur_mod,
tbl_MopoRohdaten.pos_ytm,
Left(Str([bp_msci_ic_key]),2) AS MSCI,
tbl_MopoRohdaten.pos_eop_value
FROM
qry_Position_Load_step1
LEFT JOIN tbl_MopoRohdaten ON
(qry_Position_Load_step1.MoPo_Name_Avaloq = tbl_MopoRohdaten.portf_name) AND
(qry_Position_Load_step1.ISIN = tbl_MopoRohdaten.asset_isin);
EDIT: A reduced Selection as per comments:
SELECT
tbl_MopoRohdaten.[bp_msci_ic_key] AS MSCI
FROM
qry_Position_Load_step1
LEFT JOIN tbl_MopoRohdaten ON
(qry_Position_Load_step1.MoPo_Name_Avaloq = tbl_MopoRohdaten.portf_name) AND
(qry_Position_Load_step1.ISIN = tbl_MopoRohdaten.asset_isin)
WHERE
(((tbl_MopoRohdaten.[bp_msci_ic_key]) Is Not Null));
The problem occurred because the underlying data had a broked/incomplete record source. For reasons I am not certain of yet, only a fraction of the underlying data in tbl_MopoRohdaten got loaded. Since the query used a double join in matching up the data, it kept on showing a number of records that matched one of the joins.
However, the results that were returned never contained any data for the MSCI field I was having problems with. So naturally, when I used CStr() it returned an error, because the field was Null.

SQL SELECT returns same item more than one time

I have the following SQL Command:
SELECT *
FROM Notes
INNER JOIN AuthorizedPersons
ON Notes.idPass = AuthorizedPersons.idPass
AND AuthorizedPersons.Privileged = 0
AND Notes.idUser =7
This returns the correct items! BUT returns the same item twice for each AuthorizedPerson that exists!
(Using DISTINCT does not solve the problem because items can have the same name.)
Query Results:
As you can see in the idPass 15 and 16 the description can be the same BUT idPass cannot since it's the primary key!
The query returns 3 times the idPass 30...
Try to use Where instead of the first AND.
SELECT *
FROM Notes
INNER JOIN AuthorizedPersons
ON Notes.idPass = AuthorizedPersons.idPass
WHERE AuthorizedPersons.Privileged = 0
AND Notes.idUser =7
In the table AuthorizedPersons ,column starting with 'IdUs..' repeating multiple times against the same idPass.That is why you are getting multiple rows against same value of idpass.For avoiding the duplicate records, you can either use a 'DISTINCT' keyword after excluding that particular column or you can choose any one of the record from that duplicated record by eliminating the others.

Microsoft Access Query - Can't select records when adding a date to query

I am trying to compare two tables in MS Access 2010, and select records from one table (tmp_import_table) which don't exist in the second table (referrals). This works fine with the following query:
SELECT tmp_import_table.F2, tmp_import_table.F12, tmp_import_table.F13, tmp_import_table.RefDate
FROM tmp_import_table LEFT JOIN referrals ON tmp_import_table.[F2] = referrals.[ext_referral_no]
WHERE (((referrals.ext_referral_no) Is Null));
and results in the following dataset:
However, I now need to add a second criteria to the WHERE clause in the query, and select only records which occur after a certain date, which is stored in referrals.referral_date (date/time field) I have written the following query:
SELECT tmp_import_table.F2, tmp_import_table.F12, tmp_import_table.F13, tmp_import_table.RefDate
FROM tmp_import_table LEFT JOIN referrals ON tmp_import_table.[F2] = referrals.[ext_referral_no]
WHERE (((referrals.ext_referral_no) Is Null) AND ((referrals.referral_date)>#9/10/2014#));
But the query always ends with an empty dataset! I've tried all sorts of permutations of it, but always end up with the same empty result! In addition I've tried swearing, banging my head against the wall, and alcohol, but none of these seem to have worked either...
Can anybody spot an obvious problem with my query?
Thanks for looking!
Seb
You are doing left join and selecting tmp_import_table.RefDate in the first query. But filtering by referrals.referral_date in the second one which may be/are NULLs. Change to:
....AND ((tmp_import_table.referral_date)>#9/10/2014#));

SQL query seems to work for 'AND T1.email_address_ IN (subquery)', but returns 0 rows for 'AND T1.email_address_ NOT IN (subquery)'

Good morning. I'm working in Responsys Interact, which is an Oracle-based email campaign management type SAAS product. I'm creating a query to basically filter a target list for an email campaign designed to target a specific sub-set of our master email contact list. Here's the query I created a few weeks ago that appears to work:
/*
Table Symbolic Name
CONTACTS_LIST $A$
Engaged $B$
TRANSACTIONS_RAW $C$
TRANSACTION_LINES_RAW $D$
-- A Responsys Filter (Engaged) will return only an RIID_, nothing else, according to John # Responsys....so,....let's join on that to contact list...
*/
SELECT
DISTINCT $A$.EMAIL_ADDRESS_,
$A$.RIID_,
$A$.FIRST_NAME,
$A$.LAST_NAME,
$A$.EMAIL_PERMISSION_STATUS_
FROM
$A$
JOIN $B$ ON $B$.RIID_ = $A$.RIID_
LEFT JOIN $C$ ON $C$.EMAIL_ADDRESS_ = $A$.EMAIL_ADDRESS_
LEFT JOIN $D$ ON $D$.TRANSACTION_ID = $C$.TRANSACTION_ID
WHERE
$A$.EMAIL_DOMAIN_ NOT IN ('none.com', 'noemail.com', 'mailinator.com', 'nomail.com') AND
/* don't include hp customers */
$A$.HP_PLAN_START_DATE IS NULL AND
$A$.EMAIL_ADDRESS_ NOT IN
(
SELECT
$C$.EMAIL_ADDRESS_
FROM
$C$
JOIN $D$ ON $D$.TRANSACTION_ID = $C$.TRANSACTION_ID
WHERE
/* Get only purchase transactions for certain item_id's/SKU's */
($D$.ITEM_FAMILY_ID IN (3,4,5,8,14,15) OR $D$.ITEM_ID IN (704,769,1893,2808,3013) ) AND
/* .... within last 60 days (i.e. 2 months) */
$A$.TRANDATE > ADD_MONTHS(CURRENT_TIMESTAMP, -2)
)
;
This seems to work, in that if I run the query without the sub-query, we get 720K rows; and if I add back the 'AND NOT IN...' subquery, we get about 700K rows, which appears correct based on what my user knows about her data. What I'm (supposedly) doing with the NOT IN subquery is filtering out any email addresses where the customer has purchased certain items from us in the last 60 days.
So, now I need to add in another constraint. We still don't want customers who made certain purchases in the last 60 days as above, but now also we want to exclude customers who have purchased another particular item, but now within the last 12 months. So, I thought I would add another subquery, as shown below. Now, this has introduced several problems:
Performance - the query, which took a couple minutes to run before, now takes quite a few more minutes to run - in fact it seems to time out....
So, I wondered if there's an issue having two subqueries, but before I went to think about alternatives to this, I decided to test my new subquery by temporarily deleting the first subquery, so that I had just one subquery similar to above, but with the new item = 11 and within the last 12 months logic. And so with this, the query finally returned after a few minutes now, but with zero rows.
Trying to figure out why, I tried simply changing the AND NOT IN (subquery) to AND IN (subquery), and that worked, in that it returned a few thousand rows, as expected.
So why would the same SQL when using AND IN (subquery) "work", but the exact same SQL simply changed to AND NOT IN (subquery) return zero rows, instead of what I would expect which would be my 700 something thousdand plus rows, less the couple thousand encapsulated by the subquery result?
Also, what is the best i.e. most performant way to accomplish what I'm trying to do, which is filter by some purchases made within one date range, AND by some other purchases made within a different date range?
Here's the modified version:
SELECT
DISTINCT $A$.EMAIL_ADDRESS_,
$A$.RIID_,
$A$.FIRST_NAME,
$A$.LAST_NAME,
$A$.EMAIL_PERMISSION_STATUS_
FROM
$A$
JOIN $B$ ON $B$.RIID_ = $A$.RIID_
LEFT JOIN $C$ ON $C$.EMAIL_ADDRESS_ = $A$.EMAIL_ADDRESS_
LEFT JOIN $D$ ON $D$.TRANSACTION_ID = $C$.TRANSACTION_ID
WHERE
$A$.EMAIL_DOMAIN_ NOT IN ('none.com', 'noemail.com', 'mailinator.com', 'nomail.com') AND
/* don't include hp customers */
$A$.HP_PLAN_START_DATE IS NULL AND
$A$.EMAIL_ADDRESS_ NOT IN
(
SELECT
$C$.EMAIL_ADDRESS_
FROM
$C$
JOIN $D$ ON $D$.TRANSACTION_ID = $C$.TRANSACTION_ID
WHERE
/* Get only purchase transactions for certain item_id's/SKU's */
($D$.ITEM_FAMILY_ID IN (3,4,5,8,14,15) OR $D$.ITEM_ID IN (704,769,1893,2808,3013) ) AND
/* .... within last 60 days (i.e. 2 months) */
$C$.TRANDATE > ADD_MONTHS(CURRENT_TIMESTAMP, -2)
)
AND
$A$.EMAIL_ADDRESS_ NOT IN
(
/* get purchase transactions for another type of item within last year */
SELECT
$C$.EMAIL_ADDRESS_
FROM
$C$
JOIN $D$ ON $D$.TRANSACTION_ID = $C$.TRANSACTION_ID
WHERE
$D$.ITEM_FAMILY_ID = 11 AND $C$.TRANDATE > ADD_MONTHS(CURRENT_TIMESTAMP, -12)
)
;
Thanks for any ideas/insights. I may be missing or mis-remembering some basic SQL concept here - if so please help me out! Also, Responsys Interact runs on top of Oracle - it's an Oracle product - but I don't know off hand what version/flavor. Thanks!
Looks like my problem with the new subquery was due to poor performance due to lack of indexes. Thanks to Alex Poole's comments, I looked in Responsys and there is a facility to get an 'explain' type analysis, and it was throwing warnings, and suggesting I build some indexes. Found the way to do that on the data sources, went back to the explain, and it said, "The query should run without placing an unnecessary burden on the system". And while it still ran for quite a few minutes, it did finally come back with close to the expected number of rows.
Now, I'm on to tackle the other half of the issue, which is to now incorporate this second sub-query in addition to the first, original subquery....
Ok, upon further testing/analysis and refining my stackoverflow search critieria, the answer to the main part of my question dealing with the IN vs. NOT IN can be found here: SQL "select where not in subquery" returns no results
My performance was helped by using Responsys's explain-like feature and adding some indexes, but when I did that, I also happened to add in a little extra SQL in my sub-query's WHERE clause.... when I removed that, even after indexes built, I was back to zero rows returned. That's because as it turned out at least one of the transactions rows for the item family id I was interested in for this additional sub-query had a null value for email address. And as further explained in the link above, when using NOT IN, as soon as you have a null value involved, SQL can't definitively say it's NOT IN, since you can't really compare to null, so as soon as you have a null, the sub-query's going to evaluate 'false', thus zero rows. When using IN, even though there are nulls present, if you get one positive match, well, that's a match, so the sub-query returns 'true', so that's why you'll get rows with IN, but not with NOT IN. I hadn't realized that some of our transaction data may have null email addresses - now I know, so I just added a where not null to the where clause for the email address, and now all's good.

Update table with combined field from other tables

I have a table with actions that are being due in the future. I have a second table that holds all the cases, including the due date of the case. And I have a third table that holds numbers.
The problems is as follows. Our system automatically populates our table with future actions. For some clients however, we need to change these dates. I wanted to create an update query for this, and have this run through our scheduler. However, I am kind of stuck at the moment.
What I have on code so far is this:
UPDATE proxima_gestion p
SET fecha = (SELECT To_char(d.f_ult_vencim + c.hrem01, 'yyyyMMdd')
FROM deuda d,
c4u_activity_dates c,
proxima_gestion p
WHERE d.codigo_cliente = c.codigo_cliente
AND p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
WHERE EXISTS (SELECT *
FROM proxima_gestion p,
deuda d
WHERE p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
The field fecha is the current action date. Unfortunately, this is saved as a char instead of date. That is why I need to convert the date back to a char. F_ult_vencim is the due date, and hrem01 is the number of days the actions should be placed away from the due date. (for example, this could be 10, making the new date 10 days after the due date)
Apart from that, there are a few more criteria when we need to change the date (certain creditors, certain departments, only for future cases and starting from a certain amount, only for a certain action type.)
However, when I try and run this query, I get the error message
ORA-01427: single-row subquery returns more than one row
If I run both subqueries seperately, I get 2 results from both. What I am trying to accomplish, is that it connects these 2 queries, and updates the field to the new value. This value will be different for every case, as every due date will be different.
Is this even possible? And if so, how?
You're getting the error because the first SELECT is returning more than one row for each row in the table being updated.
The first thing I see is that the alias for the table in UPDATE is the same as the alias in both SELECTs (p). So all of the references to p in the subqueries are referencing proxima_gestion in the subquery rather than the outer query. That is, the subquery is not dependent on the outer query, which is required for an UPDATE.
Try removing "proxima_gestion p" from FROM in both subqueries. The references to p, then, will be to the outer UPDATE query.