I am using this part of a sql statement to delete accounts with the specific phone number in a cronjob.php file. How do I alter this statement to test for the length of a specific given field in the user-profies, rather than what I list here as the value being LIKE '%2147483648%'
$strSQL = "DELETE
FROM users,
profile_values
USING profile_values
INNER JOIN users USING(uid)
INNER JOIN profile_fields USING(fid)
WHERE profile_values.uid=users.uid
AND profile_values.value LIKE '%2147483648%'
AND (profile_fields.name = 'profile_phone_number')";
execSQL($strSQL);
If you are testing for length of the data in the field, you can use code like:
... WHERE LENGTH(TRIM(profile_values.value)) = 10 ...
substituting the correct field name. The TRIM function is important to eliminate any leading or trailing spaces which might have crept in to the data.
Be careful using a function like this to automatically delete users. It will be quite indiscriminate.
Related
I have an Access database that I am currently working on. I have 2 tables and I want to combine both tables. The issue I am coming across is that the field I am using to match both tables is not always the same, meaning I will have to use a wildcard and I am not too sure on how to do that.
The names of my two tables are:
ACW,Hold
QMT
Query will have the following fields:
RM Field that is present on both tables.
ACW comes from table ACT,Hold
Avg Hold comes from table ACT,Hold
Score comes from table QMT.
The field I am using is "RM" however, since it is names some of them are first name last name in the first table and last name first on the other table. Also, there is extra characters in some scenarios. Is there a way to accomplish this?
I tried the following with no luck:
SELECT [ACW,Hold].RM, [ACW,Hold].ACW, [ACW,Hold].[Avg Hold], QMT.Score
FROM [ACW,Hold] INNER JOIN QMT ON [ACW,Hold].RM = QMT.RM & "*";
The SQL operator that supports wildcards is the LIKE operator, so your query should use it instead of the = operator:
SELECT [ACW,Hold].RM, [ACW,Hold].ACW, [ACW,Hold].[Avg Hold], QMT.Score
FROM [ACW,Hold] INNER JOIN QMT
ON [ACW,Hold].RM LIKE QMT.RM & "*";
I just tried a similar query in Access 2010 and it seemed to work as expected.
Update
If you need to perform matching that is more sophisticated than a single LIKE comparison can offer then you could also create a VBA function that accepts the two field values as arguments and returns a Boolean value indicating whether or not they match. For example, with a function like
Option Compare Database
Option Explicit
Public Function DoTheyMatch(product As String, ingredient As String) As Boolean
Dim result As Boolean
If product Like ingredient & "*" Then
result = True
ElseIf ingredient = "some special thing" And product = "value to match" Then
result = True
Else
result = False
End If
DoTheyMatch = result
End Function
you could use that function as the ON condition of the JOIN:
SELECT i.Ingredient, i.Supplier, p.Product
FROM Ingredients i INNER JOIN Products p
ON DoTheyMatch(p.Product, i.Ingredient);
I just tried that in Access 2010 and it worked, too.
UPDATE studentattendance
JOIN studentdetails using(matricno)
JOIN studentModules using (matricno)
SET 05/12/15 = 1
WHERE cardUid = '01545695'
Hey hows it going, I'm having trouble updating a column in my database, the column is called '05/12/15' because it's named after a date. However I'm having trouble updating it with SQL because the syntax is wrong.
How do I update it as it seems to be having trouble with the forward slashes. I've tried single quotes and square brackets but they don't work
Thanks
Using backticks permits you to use alternative characters.
SET `05/12/15` = 1
query :-
UPDATE studentattendance
JOIN studentdetails using(matricno)
JOIN studentModules using (matricno)
SET `05/12/15` = 1
WHERE cardUid = '01545695'
I am trying to update/revise the department names in a table called "DEPART_NAMES_AS_SUBMITTED" using another table called "DEPART_NAMES_REQUIRED." I would like this update to occur only if the line numbers in "DEPART_NAMES_AS_SUBMITTED" are within the line number range [LOW] [HIGH] in the second table called "DEPART_NAMES_REQUIRED." If the line number is less/more than the [LOW] [HIGH] range the department name should remain the same. I have unsuccessfully tried numerous SQLs including the following:
UPDATE DEPT_NAMES_SUBMITTED INNER JOIN DEPT_NAMES_REQUIRED ON(DEPT_NAMES_SUBMITTED.LINE_NUMBER = DEPT_NAMES_REQUIRED.HIGH) AND (DEPT_NAMES_SUBMITTED.LINE_NUMBER = DEPT_NAMES_REQUIRED.LOW) SET DEPT_NAMES_SUBMITTED.DEPART_NAME = [DEPT_NAMES_REQUIRED].[DEPART_NAME]
WHERE (((DEPT_NAMES_REQUIRED.LINE_NUMBER) Between [low] And [high]));
Thank you for taking the time to read and answer this question.
I think your query is fine if you remove the square braces and put in the right logic:
UPDATE DEPT_NAMES_SUBMITTED ns INNER JOIN
DEPT_NAMES_REQUIRED hr
ON ns.LINE_NUMBER <= nr.HIGH AND
ns.LINE_NUMBER >= nr.LOW
SET ns.DEPART_NAME = nr.DEPART_NAME;
Notice that table aliases make the query easier to write and to read.
Wondered if someone could help me write a MySQL query. I noticed in my email database I have a huge amount of users who got past my automated entry checks who I want to flag. They are all of the form abcdef123#hotmail.com where abcdef are random names of variable length, then a 3 digit number.
I have a field in my table called fld_bad, which I want to change to 1 in the query.
So something like
UPDATE tbl_users SET fld_bad = "1" WHERE fld_email .....
Obviously the ..... is where my knowledge is failing me!
you can use the mysql regexp command to do this
http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
UPDATE tbl_users SET fld_bad = "1" WHERE fld_email REGEXP '[A-Za-z]+[0-9]{3}#hotmail\\.com' = 1;
You can use:
UPDATE tbl_users
SET fld_bad = "1"
WHERE fld_email REGEXP '[[:alpha:]]+[[:digit]]{3}#hotmail\\.com'
I am having problems running a query without either truncating the note field in NotesTbl or returning repeated entries.
UID is not unique for AccessTbl. When I leave out "distinct" notes will return multiple times because I am joining with AccessTbl on a non-distinct condition. When I use distict, the note field is trunctated because it is a memo field.
Here is my query:
SELECT DISTINCT NotesTbl.pin, NotesTbl.noteid, NotesTbl.note, NotesTbl.date,
AccessTbl.affiliation, AccessTbl.name
FROM NotesTbl
LEFT JOIN AccessTbl
ON NotesTbl.UID = AccessTbl.UID
WHERE PIN = #pin#
AND UID = '#uid#'
ORDER BY NotesTbl.DATE DESC
The Access database engine normally determines uniqueness of text ('String') data using only the first 255 characters and that is why DISTINCT and GROUP BY will truncate.
This suggestion is a bit long winded but it does work: split the MEMO into chunks of 255 characters, do use DISTINCT on the chunks, then concatenate them back together again e.g. (Access database engine ANSI-92 Query Mode syntax i.e. parens for subqueries):
SELECT DT2.MyMemoCol_1 & DT2.MyMemoCol_2 AS MyMemoCol
FROM (
SELECT DISTINCT DT1.MyMemoCol_1, DT1.MyMemoCol_2
FROM (
SELECT MID(MyMemoCol, 1, 255) AS MyMemoCol_1,
MID(MyMemoCol, 256, 255) AS MyMemoCol_2
FROM Test1
) AS DT1
) AS DT2;
A comment has been posted:
Breaking the memo down in to
255-character chunks is entirely
unnecessary. You can simply sort on
Left(MyMemoCol, 8192) or some other
appropriately chosen value for the
field length returned.
Well, in my testing this doesn't work at all. Quick repro:
CREATE TABLE Test1 (MyMemoCol MEMO NOT NULL);
INSERT INTO Test1 (MyMemoCol) VALUES (STRING(300, 'A'));
INSERT INTO Test1 (MyMemoCol) VALUES (STRING(300, 'A') & STRING(5, 'X'));
INSERT INTO Test1 (MyMemoCol) VALUES (STRING(300, 'A'));
SELECT LEFT$(MyMemoCol, 8192)
FROM Test1
GROUP
BY LEFT$(MyMemoCol, 8192);
Tested using the SQL view of a Access2007 .accdb ACE engine Query object in SQL-92 Query Mode, the query returns a single row (incorrect) whose value has been truncated at 255 characters (incorrect).
The earlier 'chunking' query returns two rows (correct) without truncation (correct).
I found a solution that seems to work. I used a "group by" to force distinctness on the PIN and NoteID. I tried to exclude the note from distinctness comparissons by using First() to avoid truncation.
SELECT NotesTbl.pin, NotesTbl.noteid, First(NotesTbl.note) as notebody, NotesTbl.date,
AccessTbl.affiliation, AccessTbl.name
FROM NotesTbl
LEFT JOIN AccessTbl
ON NotesTbl.UID = AccessTbl.UID
WHERE PIN = #pin#
AND UID = '#uid#'
GROUP BY pin,affiliation,name,date,noteid
ORDER BY NotesTbl.DATE DESC
Edit: --Removed first suggestion--
...
Another method would be to break your request into two queries: One that refines AccessTbl so that UID is unique within the query, and another that joins NotesTbl to the qryAccessTblUnique query you just created.
You could also filter the query object on the CF end to remove (or ignore) responses which have already been displayed. Not efficient, but if you are using Acess, I'm guessing heavy traffic is not a huge issue.
Something like:
<cfoutput query="notes">
<cfset diplay="true">
<cfloop from="1" to="#notes.currentrow-1#">
<cfif note neq notes.note[i]>
<cfset display="false">
</cfif>
</cfloop>
<cfif display>
#note#
</cfif>
</cfoutput>
For large numbers of returns n, this is going to be ugly at O(n^2), but for small n, it should give you what you want.