When I set up Allen Browne's ConcatRelated in a query to use a date range, I get ever comment in that range in each comment field. I want to group by an assembly line name but I get each line's comments. My SQL query is below. Any help would be greatly appreciated.
I have tried a sub query but I still get the same result or a syntax error depending on how I format.
SELECT
Asm_Equipment_Rate.Line_Name,
Avg(Asm_Equipment_Rate.Std_Pnls_Lbr_Hr) AS RAsm_Line_Std_Hrs,
Sum(Asm_Prod_Data.Lbr_Hrs) AS RAsm_Line_Total_Hrs,
([RAsm_Line_Std_Hrs]*[RAsm_Line_Total_Hrs]) AS RT100_Pct_Target,
([RT100_Pct_Target]*0.9) AS RT90_Pct_Target,
Sum(Asm_Prod_Data.Produced) AS RTotal_Produced,
Sum(Asm_Prod_Data.Backflushed) AS RTotal_Backflushed,
[RTotal_Produced]/[RT100_Pct_Target] AS RAsm_Line_EFF,
Sum(Asm_Prod_Data.Scrap_Qty) AS RAsm_Scrapped_Panels,
Sum(Asm_Prod_Data.Reworked) AS RAsm_Reworked_Panels,
IIf(([RAsm_Scrapped_Panels]+[RAsm_Reworked_Panels])=0,1,1-
([RAsm_Scrapped_Panels]+[RAsm_Reworked_Panels])/([RAsm_Scrapped_Panels]+
[RAsm_Reworked_Panels]+[RTotal_Produced])) AS RFYP,
ConcatRelated
('Comments',
'Asm_Prod_Data',
'PA_date Between ' & Format([Forms]![Date Prompt]!
[txtBDate],'\#yyyy-m-d\#') & ' And ' & Format([Forms]![Date Prompt]!
[txtEDate],'\#yyyy-m-d\#'),
'Comments',
', ') AS RConCat_Comments
FROM Asm_Equipment_Rate INNER JOIN Asm_Prod_Data ON
Asm_Equipment_Rate.Equipment = Asm_Prod_Data.P_Line
WHERE (((Asm_Prod_Data.PA_Date) Between [Forms]![Date Prompt]![txtBDate]
And [Forms]![Date Prompt]![txtEDate]))
GROUP BY Asm_Equipment_Rate.Line_Name;
Regards,
Bill
change the WHERE clause to
'PA_date Between ' &
Format([Forms]![Date Prompt]![txtBDate],'\#yyyy-m-d\#') &
' And ' & Format([Forms]![Date Prompt]![txtEDate],'\#yyyy-m-d\#') &
' And P_Line=' & Asm_Prod_Data.P_Line,
You'll need to quote the value if P_Line is text.
Also, I think when you call a function you need to use double quotes inside the function call, although if what you have there is working, that's not true. Maybe it's changed for later Access versions.
EDIT: I mean the WHERE clause in the function call
Try this
SELECT
Asm_Equipment_Rate.Line_Name,
ConcatRelated
('Comments',
'Asm_Prod_Data',
'PA_date Between '
& Format([Forms]![Date Prompt]![txtBDate],'\#yyyy-m-d\#')
& ' And ' & Format([Forms]![Date Prompt]![txtEDate],'\#yyyy-m-d\#')
& ' And P_Line=' & Asm_Prod_Data.P_Line,
'Comments',
', ') AS RConCat_Comments
FROM Asm_Equipment_Rate INNER JOIN Asm_Prod_Data
ON Asm_Equipment_Rate.Equipment = Asm_Prod_Data.P_Line
WHERE (((Asm_Prod_Data.PA_Date) Between [Forms]![Date Prompt]![txtBDate]
And [Forms]![Date Prompt]![txtEDate]))
GROUP BY Asm_Equipment_Rate.Line_Name,
ConcatRelated
('Comments',
'Asm_Prod_Data',
'PA_date Between '
& Format([Forms]![Date Prompt]![txtBDate],'\#yyyy-m-d\#')
& ' And ' & Format([Forms]![Date Prompt]![txtEDate],'\#yyyy-m-d\#')
& ' And P_Line=' & Asm_Prod_Data.P_Line,
'Comments',
', ');
It's unfortunate but the GROUP BY expression has to be identical to the one in the SELECT clause, no matter how complex.
Related
I have generated unique pseudorandom numbers for each row which are subject to a particular field (Field1) in a query in Access. They have been successfully generated and I would like to fix them (kind of like copy and pasting as values). I guess my question would be, is this the best way to do this or will they always change as they are being recalculated on the query? I am open to any other suggestions, but once they have been calculated for the first time, I want them to stay as they are and not change again. Thanks!
Here is the current query's SQL:
SELECT [qry_1].*, Rnd([Field1]) AS Random
FROM qry_1;
You don't need a table. You can use a collection:
' Builds random row numbers in a select, append, or create query
' with the option of a initial automatic reset.
'
' Usage (typical select query with random ordering):
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' WHERE (RandomRowNumber(CStr([ID])) <> RandomRowNumber("",True))
' ORDER BY RandomRowNumber(CStr([ID]));
'
' The Where statement shuffles the sequence when the query is run.
'
' Usage (typical select query for a form with random ordering):
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' ORDER BY RandomRowNumber(CStr([ID]));
'
' The RandomRowID values will resist reordering and refiltering of the form.
' The sequence can be shuffled at will from, for example, a button click:
'
' Private Sub ResetRandomButton_Click()
' RandomRowNumber vbNullString, True
' Me.Requery
' End Sub
'
' and erased each time the form is closed:
'
' Private Sub Form_Close()
' RandomRowNumber vbNullString, True
' End Sub
'
' Usage (typical append query, manual reset):
' 1. Reset random counter manually:
' Call RandomRowNumber(vbNullString, True)
' 2. Run query:
' INSERT INTO TempTable ( [RandomRowID] )
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO TempTable ( [RandomRowID] )
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' WHERE (RandomRowNumber("",True)=0);
'
' 2018-09-11. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RandomRowNumber( _
ByVal Key As String, _
Optional Reset As Boolean) _
As Single
' Error codes.
' This key is already associated with an element of this collection.
Const KeyIsInUse As Long = 457
Static Keys As New Collection
On Error GoTo Err_RandomRowNumber
If Reset = True Then
Set Keys = Nothing
Else
Keys.Add Rnd(-Timer * Keys.Count), Key
End If
RandomRowNumber = Keys(Key)
Exit_RandomRowNumber:
Exit Function
Err_RandomRowNumber:
Select Case Err
Case KeyIsInUse
' Key is present.
Resume Next
Case Else
' Some other error.
Resume Exit_RandomRowNumber
End Select
End Function
It is explained in detail in my article Random Rows in Microsoft Access
(If you have no account, browse to the link: Read the full article).
Full code including a demo is on GitHub: VBA.RowNumbers
I have a function I am trying to do for a database I am working on for my job. I'm not the most proficient with Access so I apologize if I am not wording this in the best way.
What I am trying to do is create a query/macro that will mimic the behavior as shown
and result into this:
The logic is as follows
1) for each record - take the LEN of the string in StdName. Take that number of characters and UPDATE that to the Name field. The remaining characters after the LEN is moved to the 'SuffixString' Field
2)for each record - count the number of occurrences of the string in the 'StdName' field for any records ON OR BEFORE the index number and UPDATE the 'Name' field with whatever is in there already and concatenate with "_n" where n is the occurence
example: index 1 - has one occurrence of 'Car1' in the StdName Field between record 1 and record 1. index 1 'Name' is changed to Car1_1
example: index 2 - has two occurrences of 'Car1' in the StdName Field between record 1 and record 2. index 2 'Name' is changed to Car1_2
example: index 6 - has one occurrence of 'Car3" in the StdName Field between record 1 and record 6. index 6 'Name' is changed to Car3_1
Can something like this be done with an access query? I've never developed in Access before and my boss really wants to see this function kept inside access instead of being moved in an out of excel.
(I have step 1 setup this way to later put in logic where StdName does not match Name. example: "Car1_1" for Name and StdName "Car2". I realize I could just Concatenate StdName with the function in step 2 in this example i described, but I have a real world purpose of doing it this way)
This will be done on an MDB format
Thank you
You can use my RowCounter function:
SELECT RowCounter(CStr([Index]),False,[StdName])) AS RowID, *
FROM YourTable
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
or:
SELECT [StdName] & "_" & CStr(RowCounter(CStr([Index]),False,[StdName]))) AS RankedName, *
FROM YourTable
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
Edit - to update:
UPDATE s_before
SET [Name] = [StdName] & "_" & CStr(RowCounter(CStr([Index]),False,[StdName]))
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
Code:
Public Function RowCounter( _
ByVal strKey As String, _
ByVal booReset As Boolean, _
Optional ByVal strGroupKey As String) _
As Long
' Builds consecutive RowIDs in select, append or create query
' with the possibility of automatic reset.
' Optionally a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query):
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' Usage (with group key):
' SELECT RowCounter(CStr([ID]),False,CStr[GroupID])) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowCounter(vbNullString, False)
' 2. Run query:
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter("",True)=0);
'
' 2002-04-13. Cactus Data ApS. CPH
' 2002-09-09. Str() sometimes fails. Replaced with CStr().
' 2005-10-21. Str(col.Count + 1) reduced to col.Count + 1.
' 2008-02-27. Optional group parameter added.
' 2010-08-04. Corrected that group key missed first row in group.
Static col As New Collection
Static strGroup As String
On Error GoTo Err_RowCounter
If booReset = True Then
Set col = Nothing
ElseIf strGroup <> strGroupKey Then
Set col = Nothing
strGroup = strGroupKey
col.Add 1, strKey
Else
col.Add col.Count + 1, strKey
End If
RowCounter = col(strKey)
Exit_RowCounter:
Exit Function
Err_RowCounter:
Select Case Err
Case 457
' Key is present.
Resume Next
Case Else
' Some other error.
Resume Exit_RowCounter
End Select
End Function
In Telerik radrotator(legand) date is binding as system.byte:
Dim mssQL=" case when a.log_type='Schedule' then" & _
" (select case when e.schedule_type='Call Log' then cast( concat(d.user_firstname,' ',d.user_lastname,' ','Scheduled a Call On',' ',(DATE_FORMAT(e.schedule_date,'%d-%m-%Y') ) ) as char )" & _
" when e.schedule_type='Meeting' then cast(concat(d.user_firstname,' ',d.user_lastname,' ','Scheduled a Meeting On', ' ',(DATE_FORMAT(e.schedule_date,'%d-%m-%Y') )) as char )" & _
" when e.schedule_type='Mail Log' then cast (concat(d.user_firstname,' ',d.user_lastname,' ','Scheduled Mail On',' ',(DATE_FORMAT(e.schedule_date,'%d-%m-%Y'))) as char) end from crm_trn_tschedulelog e where e.log_gid=a.log_gid group by a.log_gid)"
The problem is with your CAST() and concat() functions. The concat() will give you result as system.byte when the input parameters to the function are of different types, here you are concatenating string and DATE Together. you you need to cast the Formatted Date also and remove the cast before the Concat(). Hence your query will be like the following:
concat(d.user_firstname,' ',d.user_lastname,' ','Scheduled Mail On',' ',cast (DATE_FORMAT(e.schedule_date,'%d-%m-%Y') as char)))
Hi I need to do something like this as a part of a bigger script:
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('(SUM(CASE WHEN ColumnA = "' ,ColumnA, ' "THEN 1 ELSE 0 end))/(select total
from hd_totals where ColumnA = "' ,ColumnA, ' ") AS "' ,ColumnA, ' "'))
FROM table inner join.....
The problem is that I can't do the / operation because it gives an error, even if the select output is a single value.
I don't even know how to use aliases or to store in a variable because it's a rather complex (to me) environment I'm creating here...
What about this : use CAST to have DECIMAL type, and use coalesce to prevent null values?
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('COALESCE(CAST((SUM(CASE WHEN ColumnA = "' ,ColumnA, ' "THEN 1 ELSE 0 end)) AS DECIMAL(10,4)),0)/COALESCE(CAST((select total
from hd_totals where ColumnA = "' ,ColumnA, ' ") AS DECIMAL(10,4)),0.01) AS "' ,ColumnA, ' "'))
FROM table inner join.....
Note : there is an arbitrary constant 0.01 to prevent dividing by 0.
More important note : If I was you I would also add a CASE WHEN to check that you don't divide by 0.
My problem is likely all about date formatting in a SELECT.
In an asp file I open an ADO Recordset wanting to retrieve rows of a MS SQL table that fall between date1 (08/15/2013) and date2 (08/22/2013) (i.e., the previous 7 days from today's date.)
The SELECT does retrieve the appropriate 2013 rows but also retrieves rows going back to 08/15/2012.
Here is the SELECT:
oRS.Source = "SELECT * FROM aTable WHERE entry_Date BETWEEN '" & resultLowerDate & "' AND '" & resultCurrentDate & "' AND entry_Status <> 'INACTIVE'"
resultLowerDate = 08/15/2013 and resultCurrentDate = 08/22/2013.
The table is set up as follows with resultCurrentDate = "08/22/2013":
entry_Status entry_Date (varchar) LastName FirstName SELECT Result
INITIAL 08/15/2012 Smith Jim YES
INACTIVE 08/21/2012 Green Tom no
INITIAL 08/22/2013 Jones Mary yes
FOLLOWUP 08/22/2013 Jones Mary yes
FOLLOWUP 08/22/2013 Brown Sally yes
FOLLOWUP 08/22/2013 Smith Jim yes
Any thoughts as to why the INITIAL 08/15/2012 row gets selected along with the other rows that meet the SELECT query?
STOP STORING DATES IN VARCHAR COLUMNS! And STOP CONCATENATING STRINGS, USE PROPER PARAMETERS.
Sorry to yell, but we are getting multiple questions a day where people use the wrong data type for some unknown and probably silly reason, and these are the problems it leads to.
The problem here is that you are comparing strings. Try:
"... WHERE CONVERT(DATETIME, entry_date, 101)" & _
" >= CONVERT(DATETIME, '" & resultLowerDate & "', 101)" & _
" AND CONVERT(DATETIME, entry_date, 101)" & _
" < DATEADD(DAY, 1, CONVERT(DATETIME, '" & resultCurrentDate & "', 101))"
Or better yet, set resultLowerDate and resultUpperDate to YYYYMMDD format, then you can say:
"... WHERE CONVERT(DATETIME, entry_date, 101) >= '" & resultLowerDate & "'" & _
" AND CONVERT(DATETIME, entry_date, 101) < DATEADD(DAY, 1, '" & resultCurrentDate & "'"
Note that I use an open-ended range (>= and <) instead of BETWEEN, just in case some time slips into your VARCHAR column.
Also note that this query could fail because garbage got into your column. Which it can, because you chose the wrong data type. My real suggestion is to fix the table and use a DATE or DATETIME column.
The fact that your entry_Date column is a varchar field and not an actual date is the problem. If you cast it to a datetime during the select, you'll get the results you expect.
select *
from aTable
where cast(entry_Date as datetime) between '08/15/2013' and '08/22/2013'
Sql Fiddle link