cold fusion 9: query of query displays no results - coldfusion

I have a page where I run a pretty large query:
<cfquery name="report_details" datasource="#REQUEST.prod#">
select .... from ... where ...
</cfquery>
I want to run another query based on result of this query as below, but getting no results:
<cfquery name="report_summary" dbtype="query">
select .... from report_details where ....
</cfquery>
I ran it successfully directly in database as:
select ... <--- summary query
from (
select ... from ... where ... <---- detail query
)
where ....
What am I missing?

Related

Coldfusion Query OF Query Generates more records than expected

This one has really stumped me
I have 3 queries
Query 1:
Complete query with series of where statements
Query 2 is query 1 ( minus all there where statements ) as I decide to create a query or queries instead
query 3 is the query of query where it references query 2 in the from statement and then has the where statements to filter the results received from query 2
I would expect the results from query 1 and 3 to be identical yet the query of queries outputs nearly 1500 records more than query 1
any advise suggestions why please enlighten me
<CFQUERY datasource="#Application.Workflow#" name="query1">
SELECT
*
FROM
Campaigns
INNER JOIN
CampaignReceipients
ON
Campaigns.CampaignId=CampaignReceipients.CampaignId
WHERE
Campaigns.CampaignId = 191
AND
ClientMobilePhone <> ''
AND
ClientEmailAddress like '%#%'
AND
ClientBusinessPhone is null
AND
ClientHomePhone is null
AND
AssignedToDate is null
</CFQUERY>
<CFQUERY datasource="#Application.Workflow#" name="query2">
SELECT
*
FROM
Campaigns
INNER JOIN
CampaignReceipients
ON
Campaigns.CampaignId=CampaignReceipients.CampaignId
WHERE
Campaigns.CampaignId = 191
</CFQUERY>
<cfquery dbtype="query" name="query3">
SELECT
*
FROM
query2
WHERE
ClientMobilePhone <> ''
AND
ClientEmailAddress like '%#%'
AND
ClientBusinessPhone is null
AND
ClientHomePhone is null
AND
AssignedToDate is null
</cfquery>
Without seeing your data or your DB server type, I would still be confident of this being due to how CF query of queries handles NULL values in string comparisons.
With your original datasource level query, the comparison WHERE ClientMobilePhone <> '' will ignore all records WHERE ClientMobilePhone IS NULL.
Whereas with CF QoQ, WHERE ClientMobilePhone <> '' will return records where ClientMobilePhone is either NULL or not empty string.
SQL ISNULL() / IFNULL() is not supported here, but you can test for NULL separately; you can confirm if this is definitely what is happening, by adding a fourth query to the code in your question:
<cfquery dbtype="query" name="query4">
SELECT
*
FROM
query2
WHERE
ClientMobilePhone <> '' AND ClientMobilePhone IS NOT NULL
AND
ClientEmailAddress like '%#%'
AND
ClientBusinessPhone is null
AND
ClientHomePhone is null
AND
AssignedToDate is null
</cfquery>

How To Make My Coldfusion Code More Efficient Using Query of Queries

I have some code that I am trying to make more efficient.
I am running a query and then looping through those results and running additional queries to drill down into my data even further. The code takes long to process and I'm sure that it is not as efficient as it could be and I believe that doing a query of queries would be more efficient, but I'm am not sure how to exactly implement that.
Here is my current code
My first query:
<!--- Get equipment Query --->
<cfquery name="get_equipment" datasource="#datasource#">
select *
from equipment_maintenance
where machine_type != 'unifi_site' AND machine_type != 'firewall' AND machine_type != 'dvr' AND machine_type != 'pbx' AND active = 'yes'
ORDER by #querySortType#
</cfquery>
Then I output my query and run additional queries:
<cfoutput query="get_equipment">
<!--- Get In-Progress Maintenance History --->
<cfquery name="get_in_progress_history" datasource="#datasource#">
select *
from service_ticket
where equipment_id=#id#
</cfquery>
OUTPUT SOME DATA
<!--- Update due date in the database for this machine --->
<cfquery name="dueDate#id#" datasource="#datasource#">
update equipment_maintenance
set maintenance_due_date = #dueDate#
where id = #id#
</cfquery>
OUTPUT SOME DATA
<cfquery name="get_history" datasource="#datasource#">
select *
from equipment_service_history
where equipment_id = #id#
</cfquery>
<cfquery name="get_history_ticket_detail" datasource="#datasource#">
select *
from closed_tickets
where equipment_id = #id#
order by ticket_id DESC
</cfquery>
OUTPUT SOME DATA
<cfloop query="get_history_ticket_detail">
OUTPUT SOME DATA
</cfloop>
</cfoutput>
There is a lot of HTML code in the middle for outputing my data, but that is the basic structure of my Coldfusion code.
I'm assuming that my multiple queries within my CFOUTPUT tag are what's causing the performance issues correct? How can that be fixed using QoQ?
-Brian
Here is an easy one to do. Change the update statement to
<cfquery datasource="#datasource#">
update equipment_maintenance
set maintenance_due_date = #dueDate#
where machine_type != 'unifi_site' AND machine_type != 'firewall' AND machine_type != 'dvr' AND machine_type != 'pbx' AND active = 'yes'
</cfquery>
There is no need to give it a name because it is not returning any data

Move a row to the beginning of a query

I have a recordset of messages, some of which are are from a group named "ADMIN". I want all the messages from the "ADMINS" placed at the top of the query object but I can't re-order them within the original query -- I have to do it after I already have the query object. I have a way to see which rows are from "ADMINS" but I'm not sure the best way to extract them from the query object and put them at the top.
<!--- this is the query object of all the messages --->
<cfset messageData = application.message.getMessages(inboxID)>
<!--- this returns a list of which users inside the recordset are ADMINS --->
<cfset getAdmins = application.message.getAdmins(valueList(messageData.useridfk)) />
Now I want to take all the UserIDs returned in #getAdmins#, remove the messages that are theirs in #messageData# and put them at the top of #messageData# so I can output the results. Is this a QoQ or is there a better way?
I can't really get my head around the QoQ, but I'm taking a stab at it. IS there a better way then doing THREE different QoQs?
<!--- this gets all the rows from Admins --->
<cfquery name="getAdminAnswers" dbtype="query">
SELECT *
FROM messageData
WHERE useridfk in ('#getAdmins.id#')
ORDER BY UpvotesNum DESC, posted DESC
</cfquery>
<!--- this gets all the rows from non-RDs --->
<cfquery name="getNonAdminAnswers" dbtype="query">
SELECT *
FROM messageData
WHERE useridfk NOT IN ('#getAdmins.id#')
ORDER BY UpvotesNum DESC, posted DESC
</cfquery>
<!--- join the queries with a UNION in a QoQ --->
<cfquery dbtype="query" name="data">
SELECT * FROM getAdminAnswers
UNION
SELECT * FROM getNonAdminAnswers
</cfquery>
Answer:
Got it: Like this:
<!--- this combines two queries into one --->
<cfquery name="data" dbtype="query">
SELECT *, 1 sortCol
FROM messageData
WHERE useridfk in ('#variables.getAdmins.id#')
UNION
SELECT *, 2 sortCol
FROM messageData
WHERE useridfk NOT IN ('#variables.getAdmins.id#')
ORDER BY sortCol, UpvotesNum DESC, posted DESC
</cfquery>
I can't see that there's a more expedient way of doing this without using QoQ, no. It's kinda what it's for: these exceptional circumstances where the app needs both the original data as from the DB, and a variation of it as well.
Can you say
SELECT *,
(CASE WHEN USERIDFK IN ('#getadmins.id#') THEN 1 ELSE 0 END) as mRank
FROM MessagesTableName
ORDER BY mRank DESC, UpvotesNum DESC, posted DESC
That would be the SQL Server Syntax anyway, I'm not sure what SQL flavor you're using.
I realize that all three queries are QoQs, but with just one query to get your admin list, this direct query to the db might work.
(Previously, I was unsure if you could use CASE in QoQ. You can't, so if this works at all, it would have to a direct query to the database.)

CFQuery 'WHERE' from results of another query?

I'll explain the 'real life' application of this so it's easier to understand.
I'm working on an eCommerce app that has a category structure. It starts at the top level and gradually moves down through subcategories. For example Home > Electronics > TVs > Plasma
I'm using a single page for this, showing the 'home' page if no category is defined, the subcategories if there are any, and finally the products if there are no subcategories.
This all works fine, however when I get to the 2nd part - displaying subcategories, the page is a little empty. Therefore, I'd like to display a selection of products that span all of the subcategories applicable.
This is where I'm struggling - in most cases, there will be a few subcategories. However, I'm not sure how to structure the 'where' query using the results of the previous query (code snippets below for reference).
I don't believe QofQ would be worth exploring, and I've made a vain attempt at doing something with substrings, without success.
Any pointers much appreciated!
<cfquery name="getcategories">
SELECT p.ID AS CategoryID, p.Cat_Name as CategoryName, p.Cat_Shortname, c.ID AS SubCategoryID, c.Cat_Name as SubCategoryName, c.Cat_Shortname AS SubCatShortname
FROM product_categories p LEFT JOIN product_categories c ON p.ID = c.SubcategoryOf
WHERE p.SubcategoryOf = 0
</cfquery>
<cfif IsDefined('url.cat')>
<!--- Look for additional subcategories --->
<cfquery name="getsubcategories">
SELECT *
FROM product_categories
WHERE Subcategoryof='#url.cat#'
</cfquery>
<cfquery name="getproducts">
SELECT *
FROM products
WHERE categoryid='#url.cat#'
ORDER BY RAND()
</cfquery>
</cfif>
Assuming your products table contains a subcategoryID of some kind you can use the following to get a list of sub category IDs from the query getsubcategories:
<cfset subCategoryIDs = valueList(getsubcategories.subCategoryID) >
This will give you a list of all subCategoryIDs. You can the feed this into the getproducts query like so:
<cfquery name="getproducts">
SELECT *
FROM products
WHERE subCategoryID in (<cfqueryparam cfsqltype="cf_sql_integer" value="#subCategoryIDs#" list="true">)
ORDER BY RAND()
</cfquery>
You should always cfqueryparam your query parameters.
If i understand your database structure, this query should return all products in all subcategories.
<cfquery name="getallproducts">
SELECT *
FROM products p LEFT JOIN product_categories pc ON p.categoryID = pc.ID
WHERE pc.Subcategoryof= <cfqueryparam cfsqltype="cf_sql_integer" value="#url.cat#">
</cfquery>
note: you really do want to use cfqueryparam here.

can't define id ColdFusion

here is my ColdFusion code:
Example1:
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT PRODUCT_CATID
FROM PRODUCT_CAT
WHERE PRODUCT_CATID = PRODUCT_CATID
</cfquery>
#get_brand.product_catid#
But it shows all the time number 1, i just can't understand why, and how do i make it work properly, this code should have defined the brand_id, but instead shows 1.
The system is Workcube.
Here is my example for getting from the static product's id, its dynamic price:
Example 2:
<cfset product_id = 630>
<cfquery name="price_standart" datasource="#dsn3#">
SELECT
PRICE_STANDART.PRICE PRICE
FROM
PRICE_STANDART
WHERE
PRICE_STANDART.PRODUCT_ID =
<cfqueryparam value="#product_id#" cfsqltype="cf_sql_integer">
</cfquery>
But this time i need to get from dynamic product's ID its dynamic brand id.
This script works the same way as the Example 1:
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT BRAND_ID
FROM PRODUCT_BRANDS
WHERE BRAND_ID = BRAND_ID
</cfquery>
#get_brand.BRAND_ID#
As Andreas shows in his code, your query isn't going to work as written. The statement WHERE PRODUCT_CATID = PRODUCT_CATID doesn't actually pass a value - it would actually just be self-referential within the table values. In this case, it would return everything in the table.
You should instead have:
WHERE PRODUCT_CATID = #PRODUCT_CATID#
Where #PRODUCT_CATID# represents a variable. Better yet, use cfqueryparam as Andreas shows (this prevents SQL injection and improves query performance). However, I am not even sure that is what you intend since if you have the product ID why do you need to get it from the database? Instead, I assume you probably want to get the brands from the product in a particular category. Not knowing your table structure, it's hard to write that query for you but it might look something like:
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT PRODUCT.BRAND_ID
FROM PRODUCT
INNER JOIN PRODUCT_CAT
ON PRODUCT.PRODUCT_CATID = PRODUCT_CAT.PRODUCT_CATID
WHERE PRODUCT_CATID = <cfqueryparam cfsqltype="cf_sql_integer" value="#product_catid#">
</cfquery>
Lastly, as both comments indicate, you would need to loop through the results to see all the records returned.
You need to wrap the statement in tags like this.
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT PRODUCT_CATID FROM PRODUCT_CAT WHERE PRODUCT_CATID = PRODUCT_CATID
</cfquery>
<cfoutput query =GET_Brand">
#get_brand.product_catid#
</cfoutput>
It's not very clear what your question really is about, but let me guess:
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT PRODUCT_CATID
FROM PRODUCT_CAT
WHERE PRODUCT_CATID = <cfqueryparam cfsqltype="cf_sql_integer" value="#product_catid#">
</cfquery>
where #product_catid# refers to a variable you defined earlier in your code or received via form or url scope.
<cfloop query="GET_BRAND">
#get_brand.product_catid#<br />
</cfloop>
will show a list of all the product_catid's returned by the query.
It's not too clear what you are after here, but in the queries there are at least 2 problems. First your WHERE clause
WHERE PRODUCT_CATID = PRODUCT_CATID
is like saying
WHERE 1=1
This will return the full recordset. You can see this by adding
<cfdump var="#GET_BRAND#">
under your code to see the query output. I'm guessing this will show all records in the table.
To match just one record you need your WHERE clause to be like
WHERE PRODUCT_CATID = 3
or have the #...# wrapped around the variable you are trying to match to make it dynamic.
Secondly to the query result may be more than one record, and to see any more than the first record you need to loop over the output. One way is to use
<cfoutput query="GET_BRAND">
#BRAND_ID# <br>
</cfoutput>
My guess of what you are after is
<cfset ID_TO_MATCH=3>
<cfquery name="GET_BRAND" datasource="#dsn1#">
SELECT BRAND_ID
FROM PRODUCT_CAT
WHERE PRODUCT_CATID = #ID_TO_MATCH#
</cfquery>
<cfoutput query="GET_BRAND">
#BRAND_ID# <br>
</cfoutput>