Attempting to pull concatenated Q-urls, using data-type in a table - mysql

Will try and explain as concisely as I can.
Below is a dummy query based on one I'm attempting to edit.
I'm trying to return two different types which are pulled from the same table.
The first type of data is a numeric (a score from 1-10)
The next type of data is a both numbers and letters, used to complete a URL.
My problem is that the concat statement to return only null values. when I use the and statement to specify only URL data, the other column returns only null values.
Is there a way I can change this, to pull only one type of data in one column separate to the other?
Cheers
select
concat("example.com/",rs.answer,"/415x380.png") as Q_URL,
Ease_of_use.score as "Ease_Of_use"
from customer_feedback c
left join response_data Ease_of_use on (Ease_of_booking_use.response_overall_id=c.id and Ease_of_use.data_type_id=1536)
left join response_data rs on rs.customer_review_id=c.id
join data_type dt on dt.id=rs.data_type_id
where c.retailer_id in (678,1651)
and rs.answer is not null
and dt.response_type="photo_URL"
group by c.id

I'm not sure what you mean by "I use the and statement to specify only URL data", but I would use isnull function to provide a default value for NULLS
concat("example.com/",isnull(rs.answer,"default value"),"/415x380.png")
rather than using rs.answer is not null

Related

How to pass variable for LIKE operator to accommodate a value and NULL values

I am having some troubling with filtering database information on my website. I have two tables, an equipment database equipment_database and qr codes linked to specific equipment qr_links. So I am using a search function to filter the data using a LIKE operator. In cases where all entries are selected I would use %% and when specific parts are searched would be %search_pattern%. The problem is that not all equipment have a matching qr code. Therefore when using the LIKE operator it does not return rows with NULL values and returns only entries that have a linked qr code. Searching the qr code is optional and all entries with or without qr codes should be returned. Here is an example of the MySQL query:
SELECT equipment_database.equipment_id, equipment_database.equipment_type, equipment_database.equipment_name, qr_links.qr_linked_with_id, qr_links.qr_link_code
FROM equipment_database
LEFT JOIN qr_links
ON equipment_database.equipment_id=qr_links.qr_linked_with_id
WHERE equipment_database.equipment_institute_id=?
AND equipment_database.equipment_institute_branch_id=?
AND equipment_database.equipment_status=?
AND CONCAT (equipment_database.equipment_name, equipment_database.equipment_type, qr_links.qr_link_code)
LIKE ?
ORDER BY equipment_database.equipment_name
LIMIT ?, ?;
Is there any way that NULL values form the qr_links could be included when using the LIKE operator (so %% returns all values plus those with NULL values).
Thank you!
try changing you query like below. Using MySQL IFNULL(column, "value to return if null") function, we can get an empty string returned instead of NULL.
SELECT equipment_database.equipment_id, equipment_database.equipment_type, equipment_database.equipment_name, qr_links.qr_linked_with_id, qr_links.qr_link_code
FROM equipment_database
LEFT JOIN qr_links
ON equipment_database.equipment_id=qr_links.qr_linked_with_id
WHERE equipment_database.equipment_institute_id=?
AND equipment_database.equipment_institute_branch_id=?
AND equipment_database.equipment_status=?
AND CONCAT (equipment_database.equipment_name, equipment_database.equipment_type, IFNULL(qr_links.qr_link_code, ""))
LIKE ?
ORDER BY equipment_database.equipment_name
LIMIT ?, ?;

The Value expression for the textrun ‘Textbox15.Paragraphs[0].TextRuns[0]’ contains an error: [BC30201] Expression expected

I received this error when I am trying to run a select statement in a text box in SSRS. So, basically, I am trying to return a field which is not in the given dataset. So I have run a subquery which returns the value using the existing dataset as a container.
But I don't know how to represent that return value in the Expression field. Because the expression field returns a value which is within the dataset provided.
I have provided the SQL that I have written.
Any suggestions would be much appreciated.
My intention is to return the "CommentText" value. However, the dataset does not contain any commenttext field, but an EmpID field. So I have created the subquery below that brings up the CommentText from LaborDtlComment table and when it matches with the EmpID in the report dataset it returns the CommentText Value.
select [CommentReturnQuery].[LaborDtlComment_CommentText] as [LaborDtlComment_CommentText],
[EmpBasic].[EmpID] as [EmpBasic_EmpID]
from Erp.EmpBasic as EmpBasic
inner join (select [LaborDtlComment].[CommentText] as [LaborDtlComment_CommentText],
[LaborDtl].[EmployeeNum] as [LaborDtl_EmployeeNum]
from Erp.LaborDtlComment as LaborDtlComment
inner join Erp.LaborDtl as LaborDtl on LaborDtlComment.Company = LaborDtl.Company
and LaborDtlComment.LaborHedSeq = LaborDtl.LaborHedSeq
and LaborDtlComment.LaborDtlSeq = LaborDtl.LaborDtlSeq) as CommentReturnQuery
on EmpBasic.EmpID = CommentReturnQuery.LaborDtl_EmployeeNum
My aim is to show the CommentText value in a text field. So I will create the
text field and it will contain the SQL that I have written. Can anyone help
me in this case?
It maybe simpler to use the SSRS function lookup (single paired 1 to 1) or lookupset (multiple 1 to many).microsoft lookup reference
You will have to create the query/dataset to return CommentText from LaborDtlComment table with the EmpID

LIKE clause not returning when comparing numbers with single quotes

I have a query contains a field transaction_id and data type integer.
In the WHERE condition of below query I have LIKE operator, in this case if I give transaction_id LIKE '00412552' I am not getting data.
Suppose if I give transaction_id LIKE 00412552 then I am getting data.
I think it is not taking string type as operator, please suggest what is the problem.
SELECT DISTINCT crt.carton_no,
crt.shipment_ref_no,
crt.put_away_location,
crt.item_category,
crt.total_quantity
FROM carton crt
RIGHT OUTER JOIN pick_list pl
ON (crt.carton_no = pl.carton_no AND
crt.shipment_ref_no = pl.shipment_ref_no)
WHERE pl.transaction_id LIKE '00412552'

inserting a string to a prepared statement without ' '

I have the following sql statement:
Select i.imageID, theImage, translationRating
From images i
inner join translationchains t
on t.imageId = i.imageid
where i.userID=(someUserID) And i.translated =0
and t.targetLang in (select targetLang from translationChains)
I want to make it a prepared statement to use in my java code:
Select i.imageID, theImage, translationRating
From images i
inner join translationchains t
on t.imageId = i.imageid
where i.userID=? And i.translated =0
and t.targetLang in (select ? from translationChains)
the input for the first ? is a user Id (integer) and it's working fine.
the second input is a string which containing a languageId - it's a string that either contain a number that represent a language, or the string "targetLang" which is the name of the column (=all langs)
in my java code I did the following:
Image.setInt(1, userID);
Image.setString(2, langID);
Image.executeQuery()
my problem is when I'm sending the string "targetLang" as the second parameter
the prepared statement is inserting it as 'targetLang' (with ' before and after'), with numbers it's not a problem beacuse 3='3', but with strings it is giving me different results from what I need - I always get an empty result set because nothing is equal to 'targetLang'.
I need to insert this string to the prepared statement without the '.
is it possible or I need to use something differ from prepared statement?
I know I can build a string that contain all this query but I'm looking for something more elegant
tnx
edit:
This is the Create table translationChains:
Create Table if not exists TranslationChains (
ImageID int (10) NOT NULL,
SourceLang int NOT NULL,
TargetLang int NOT NULL,
Translated tinyint default 0,
Translation text,
Translator varchar (30),
CONSTRAINT translate_image PRIMARY KEY (ImageID,SourceLang, TargetLang),
FOREIGN KEY (ImageID) REFERENCES Images(ImageID) ON DELETE CASCADE,
FOREIGN KEY (SourceLang) REFERENCES Languages(languageID) ON DELETE CASCADE,
FOREIGN KEY (TargetLang) REFERENCES Languages(languageID) ON DELETE CASCADE)
As you can see, I am trying to take images according to the "targetLang" column which is an int column. Each number represent a language.
Now I have two options in selecting images from that table:
Choosing a specific language, i.e. giving a number as the second input.
Choosing all languages, i.e. setting the second input to be the column name "targetLang".
So I am not comparing to the fixed string "targetLang". I want to choose all values possible for this column (select targetLang from translationChains).
Query parameters can take the place of a literal value only -- i.e. where you would normally put a quoted string literal, a quoted date literal, or a numeric literal. Thus a string value will always be interpreted as a string literal, as if you had put it into the query with single-quotes.
For column names, table names, SQL expressions, SQL keywords, etc., you have to interpolate these values into the SQL query prior to the call to prepare().
To be safest, use whitelisting so that user input is never interpolated into SQL queries verbatim. Always validate the user input (or any other content) before using it in a query.
I have written many examples of whitelisting when building an SQL query.
You can also see examples in my presentation SQL Injection Myths and Fallacies and my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
Re your comment:
I'm not sure exactly what you are doing. It sounds like you either want t.targetLang to equal to a literal number, or a fixed string 'targetLang'. If so, I don't know why you're doing a subquery at all -- you should just use a query parameter for a value:
where i.userID = ? And i.translated = 0
and t.targetLang = ?
Image.setString(2, langID); // either '3' or 'targetLang'
But I'm not sure I understand your description fully. Does the number represent the position of a column you want to compare against? On the same row as t.targetLang? If so, I still don't think you need a subquery. You could use an expression like the following:
where i.userID = ? And i.translated = 0
and FIELD(t.targetLang, t.targetLang, t.column2, t.column3, t.column4) = ?
Image.setString(2, '1'); // for the case where you allow all langs
Image.setString(2, '3'); // for the case where you want to match a specific column.
See the manual on the FIELD() function in MySQL, which searches for the first argument among a list of expressions. It returns the integer position of the field that matches.
Using this method, you pass the position you want your t.targetLang to match, and this allows you to pass the dynamic part as a value, instead of as a column name. It also allows you to avoid the subquery.
If I've still got it wrong and don't understand your problem, please edit your original question and provide more detail. SHOW CREATE TABLE translationChains would help. Also can you answer some of things I had to make assumptions about, e.g. are you trying to match t.targetLang against a value in another column on the same row?
Okay, now I understand your goal better. Here's a query that does what you want:
SELECT i.imageID, theImage, translationRating
FROM Images i
INNER JOIN TranslationChains t
ON t.imageId = i.imageid
WHERE i.userID = ? AND i.translated = 0
AND ? IN (t.targetLang, 'targetLang')
You can pass as the second parameter either an integer to match against the t.targetLang, or else the literal string 'targetLang' which will match against the value 'targetLang' in the predicate.
I can't recommend this solution, though, since it will probably not use indexes very well, it may have to perform type conversions by comparing the string parameter to the integer column.
The better practice when you want to match all languages is to execute the query without the last term in the WHERE clause. That is, in your application, append that term conditionally, only when you want the query to fetch a specific language. Otherwise, omit that term and skip the Image.setString().
String sql = "SELECT i.imageID, theImage, translationRating
FROM Images i
INNER JOIN TranslationChains t
ON t.imageId = i.imageid
WHERE i.userID = ? AND i.translated = 0 ";
if (langId) {
sql += " AND ? IN (t.targetLang, 'targetLang')";
}
. . .
Image.setInt(1, userID);
if (langId) {
Image.setString(2, langID);
}
Image.executeQuery()
You can change:
and t.targetLang in (select ? from translationChains)
To:
and (
(
? = 'targetLang' and
t.targetLang in (
select
targetLang
from
translationChains
)
)
or
? = t.targetLang
)
and making setString(3,langId), i.e. making 3rd parameter same as 2nd. By no way, this is more elegant or more efficient in my knowledge, but something that should work!

mysql get column name when column value matches constraint

I'm trying to get column names from a table. I want to supply the row id and I want only the column names for which the value of that column for the specific row (identified by the id) is "true" (my table has a bunch of boolean fields).
I want something like:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME.value = true
AND TABLE_THE_COLUMN_IS_FROM.id = "some_id"
Where .value would be variable, basically checking each column to see if it were true.
I know I can just get the row's values and iterate through, returning only those with value true, but I wanted to see if there is a way to do it all in one step. Thanks in advance to anyone who knows!
There is no means in one query to dynamically scan through the table's schema and inspect its values. The best way to achieve what you want is the one you suggested: query for the row client-side and then cycle through the columns searching for the values you seek. The other alternative is to query for the table schema using the INFORMATION SCHEMA views client-side, build a SQL statement with a where clause that looks for a True value in all the boolean columns, execute that and inspect the results.
This is probably going to be rather ugly no matter how you cut it, but here's one option:
select columns.column_name
from bool_table
inner join information_schema.columns
on columns.table_schema = 'your_db'
and columns.table_name = 'bool_table'
and ((columns.column_name = 'bool_1' and bool_table.bool_1 = 1)
or (columns.column_name = 'bool_2' and bool_table.bool_2 = 1))
where bool_table.id = 25
You could also potentially query information_schema.columns to dynamically generate the list of column statements so that you could dynamically generate the query, and even execute it in a stored proc using dynamic sql in mysql.