Coldfusion query of queries case like statement - coldfusion

I asked this question before, and although it was answered, it really didn't solve my issue, since as far as I can tell CF QoQ doesn't support the CASE statement.
Here is the other question: Background
So is there an easier way to accomplish what I'm trying to do, without using CASE statement in the sql, or am I going to have to just go back to the union style answer I originally came up with?
This is what I've come up with:
<cfquery name="range1" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 <= 15000
</cfquery>
<cfquery name="range2" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 <= 30000
</cfquery>
<cfquery name="range3" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 <= 45000
</cfquery>
<cfquery name="range4" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 <= 60000
</cfquery>
<cfquery name="range5" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 <= 75000
</cfquery>
<cfquery name="range6" dbtype="query">
select count(col1) as cnt
from tbl1
where col1 > 75000
</cfquery>

The union style is appropriate, but your implementation might not be correct. You have this:
select count(col1) as range1
from tbl1
where col1 <= 15000
union
select count(col1) as range2
from tbl1
where col1 > 15001 and col1 <= 30000
etc...
If you run that you will end up with a single column and won't be able to determine what each row represents. Something like this would be better.
select 'less than 15000' range, count(col1) records
from tbl1
where col1 <= 15000
group by range
union
select '15001 to 30000' range, count(col1) as records
from tbl1
where col1 > 15001 and col1 <= 30000
group by range
etc...

Related

Compare a date in CFQUERY to current month

I am running a cfquery to pull records from a table:
<cfquery name="get_followups_monthly" datasource="#datasource#">
SELECT
a.DisplayName
, count(*) AS requested_count
FROM
users AS a
INNER JOIN
ticket_followup b ON b.requested_by = a.displayName
WHERE
a.active = 1 AND b.date_of_followup_request < '2022-02-01'
GROUP BY
a.DisplayName
ORDER BY requested_count DESC
</cfquery>
I would like to compare the dates returned in column b.date_of_followup_request to see if falls within the current month.
I looked through the builtin functions but don't see anything for that. How can this be accomplished?

Sql to proc sql conversion

I have 2 tables that contains var values like (ID, date, var1,var2,var3....)
I need to get the data from table2 and add it to table1 for which (ID or date) does not exist in table1.
I am using the below code in sql to get new ID's from tab2 to tab1:
INSERT INTO table1
SELECT * FROM table2 a
WHERE ID not in(select ID from table1 where ID=a.ID)
Here is the code to add new date for existing ID's in tab2 to tab1 :
INSERT INTO table1
SELECT * FROM table2 a
WHERE date not in(select date from table1 where ID=a.ID)
I don't know how to do this in proc sql.
Please share an effective method to do this task.
To insert the new ID I used:
proc sql;
create table lookup as
select a.ID
from table1 a inner join table2 b
on a.ID = b.ID
;
insert into table1
select * from table2 a
where a.ID not in (select ID from lookup)
;
quit;
This works well. But, it failed to insert a date for existing IDs.
Please suggest some ideas to complete this step.
Thanks in advance!
SAS SQL is Similar to the SQl you have written.
The SAME insert statements can be warped as proc sqls in SAS and they work like charm.
If your SQL did work then the following will work too.
PROC SQL;
INSERT INTO work.table1
SELECT * FROM work.table2 a
WHERE ID not in(select ID from work.table1 where ID=a.ID);
INSERT INTO work.table1
SELECT * FROM work.table2 a
WHERE date not in(select date from work.table1 where ID=a.ID)
QUIT;

Distinct QoQ automatically applying order by

I am using CFSpreadsheet to read a .xlsx file.
The file has about 3000 duplicates which I can safely ignore so I thought I'd do a select distinct QoQ but once I do this, the results are ordered as if order by col_1, col_2 was added to the query which is a very bad thing.
<cfspreadsheet query = "qSheet" ...>
<cfquery dbtype="query" name = "qDistinctSheet">
select distinct
col_1
, col_2
from
qSheet
</cfquery>
<cfdump var = "#qDistinctSheet#">
If I remove distinct I get the expected results which SHOULD be:
[empty string]
Name
John
John
Adam
Steve
Bob
Bob
When I add distinct I get
[Empty String]
Adam
Bob
John
Name
Steve
Any idea how to prevent this unwanted ordering?
Edit
End solution is to apply a row number and use group by as suggested by Matt and Dan
<cfset ids = []>
<cfloop query="qSheet">
<cfset ids[qSheet.currentRow] = qSheet.currentRow>
</cfloop>
<cfset queryAddColumn(qSheet,"id",ids)>
<cfquery dbtype="query" name="qDistinct">
SELECT
col_1
, col_2
, min(ID) AS firstID
FROM
qSheet
GROUP BY
col_1
, col_2
ORDER BY
firstID
</cfquery>
You can use a GROUP BY option instead and use the ID row from the spreadsheet query
<cfquery dbtype="query" name="qDistinct">
SELECT
col_1
, col_2
, min(ID) AS firstID
FROM
qSheet
GROUP BY
col_1
, col_2
ORDER BY
firstID

ColdFusion: cfqueryparam for binary values

I wrote the below query based on the help provided in this link, querying binary column using like in sql server
SELECT * FROM myTable
WHERE TestData >= 0x00010000
AND TestData < 0x00020000;
It returned the expected results. I used cfqueryparam and updated the query as:
SELECT * FROM myTable
WHERE TestData >= <cfqueryparam value="0x00010000" cfsqltype="cf_sql_binary">
AND TestData < <cfqueryparam value="0x00020000" cfsqltype="cf_sql_binary">;
but it returned with errors, Error Message: Invalid data 0x00010000 for CFSQLTYPE CF_SQL_BINARY.
I tried with cfsqltype="CF_SQL_BLOB" but no results.
How to fix this issue? Thanks in advance
As it stands, there's nothing inherently wrong with keeping the query as:
SELECT * FROM myTable
WHERE TestData >= 0x00010000 AND TestData < 0x00020000
(You should ideally be listing individual columns rather than using * though.)
However, whilst there is no security benefit to parameterising these queries (they have no variables and thus are not prone to SQL injection), there may still be a benefit of having parameterised SQL for the purpose of caching a single execution plan.
If you have multiple queries, of the form:
<cfquery...>
SELECT * FROM myTable
WHERE TestData >= 0x00010000 AND TestData < 0x00020000
</cfquery>
<cfquery...>
SELECT * FROM myTable
WHERE TestData >= 0x00020000 AND TestData < 0x00030000
</cfquery>
<cfquery...>
SELECT * FROM myTable
WHERE TestData >= 0x00030000 AND TestData < 0x00040000
</cfquery>
Using cfqueryparam for these would allow a single execution plan to be cached for the multiple queries, potentially leading to better performance.
In this situation, you need to use BinaryDecode to convert your hex string into a binary value that cfqueryparam can handle, like so:
<cfquery...>
SELECT * FROM myTable
WHERE TestData >= <cfqueryparam value=#BinaryDecode('00010000','Hex')# cfsqltype="cf_sql_binary" />
AND TestData < <cfqueryparam value=#BinaryDecode('00020000','Hex')# cfsqltype="cf_sql_binary" />
</cfquery>
(Note that the 0x prefix is ommitted.)

Coldfusion 2 queries comparison

I have 2 Query object in Coldfusion now I want to create a small report on account of these 2 queries
queries may look like
Q1
ID CODE NAME ACTIVE
and
Q2
CODE PRICE BOOKABLE
The code CODE
field is common key between these 2 queries. Now I want to get records are that are in Q1 but not in Q2 and vice versa, how many recodes are common in both queries where CODE is unique.
<cfquery name="Q1" datasource="test">
select * from users where code not in (select code from system)
</cfquery>
<cfquery name="Q2" datasource="test">
select * from system where code not in (select code from users)
</cfquery>
you can use QoQ to solve this.
<cfquery name="Q1" datasource="test">
select * from table1
</cfquery>
<cfquery name="Q2" datasource="test">
select * from table2
</cfquery>
<cfset q1code = valuelist(q2.code,"," )>
<cfset q2code = valuelist(q1.code,"," )>
<cfquery name="q3" dbtype="query" >
select * from q1 where code Not in(#q1code#)
</cfquery>
<cfquery name="q4" dbtype="query" >
select * from q2 where code Not in(#q2code#)
</cfquery>
<cfquery name="q5" dbtype="query" >
select * from q1,q2 where q1.code = q2.code
</cfquery>
Agree with other people, make the DB do the work. If these are in the same db, then you do this to get the records common to both tables:
SELECT Q1.ID
,Q1.CODE
,Q1.NAME
,Q1.ACTIVE
,Q2.PRICE
,Q2.BOOKABLE
FROM Q1, Q2
WHERE Q1.CODE = Q2.CODE
In order to do the first part of your question .. get the records that are in Q1 but not in Q2, you can do that with an outer_join if I am understanding you correctly. Syntax is different for all db's on doing outer joins. I always have to go look it up, so I'm not going to write it here.
another option is to union the two tables, and let cold fusion pull the reports on column_name = ''
select * from Q1 UNION SELECT * FROM Q2
-- you can't actually do this (select *) because of duplicate 'code' column in both dbs.
you'll have to specify the columns explicitly and rename the first one to Q1Code, then Q2Code.
then in CF you do
<cfif q2Code EQ ''> print Q1: #Q1CODE# <cfelse> print Q2: #Q2CODE# </cfif>
or maybe you want:
<cfif q1code EQ Q2code> yay they match</cfif>