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?
Related
I have two tables:
Users (2 columns): ID, DisplayName, Active
Ticket_Followups (4 colums): id, requested_by, requested_date, ticket_id
I am tryiwng to group all the similar records in the ticket_followup table, first by recordcount and then by displayName.
Here is what I have so far:
<cfquery name="active_users" datasource="#datasource#">
select * from users
where active='1'
</cfquery>
<cfloop query="active_users">
<cfquery name="get_followups" datasource="#datasource#">
select date_of_followup_request, requested_by, ticket_id
from ticket_followup
where requested_by = '#active_users.displayName#'
</cfquery>
<cfoutput>
<tr>
<td>#active_users.displayName#</td>
<td>#get_followups.recordcount#</td>
</tr>
</cfoutput>
</cfloop>
I am able to successfully show the output for the total records by user, but there is no order to the output. I would like to group it so that it shows the DisplayName with the highest recordcount first, descending in order.
How can I do that?
This is a SQL issue, CF is just displaying data after the data is gathered.
You need to do this in one query.
You need to associate the ticket follow ups by user ID, not by name (Name could change, but not the ID).
There's a table of tickets I assume, but we'll stick to your two tables.
First, the tables:
Users
----------
id
DisplayName
Active
Ticket_Followups
----------
id
requested_by_id (Users.id)
requested_date
ticket_id
You can technically join by name, but it's a much slower query and I've no idea how much data you have.
This query joins the two tables and gives you a count of ticket follow ups by user. You can add an ORDER BY statement before the GROUP BY depending on your needs.
SELECT
a.DisplayName
, count(*) AS requested_count
FROM
Users AS a
INNER JOIN
Ticket_Followups b ON b.requested_by_id = a.id
WHERE
a.active = 1
GROUP BY
a.id
If you don't do this in one query, then for every user that has an active ticket, you're making another query.
10 users, 11 queries
20 users, 21 queries
etc.
Updated 2022-02-15
Query using DisplayName with an ORDER BY clause. This should make it clearer that you're counting the tickets per user and not the number of users.
SELECT
a.DisplayName
, count(a.*) AS ticket_count
FROM
Ticket_Followups AS a
INNER JOIN
Users AS b ON b.DisplayName = a.DisplayName
WHERE
a.active = 1
ORDER BY
a.DisplayName DESC
GROUP BY
a.DisplayName
Output:
<cfoutput query="queryName">
<li>#queryName.DisplayName# - #queryName.ticket_count#</li>
</cfoutput>
I have an AWS database with multiple tables that I am trying to get the row counts for in a single query.
The ideal query output would be:
table_name row_count
table2_name row_count
etc...
So far I've been able to either get all the table names from the database or all the rowcounts of the tables (in random order), but not both in the same query.
This query returns a column of all the table names that exist in the database:
SELECT table_name FROM information_schema.tables WHERE table_schema = '<database_name>';
This query returns all the row counts for the tables:
SELECT COUNT(*) FROM table_name
UNION ALL
SELECT COUNT(*) FROM table2_name
UNION ALL
etc..for the rest of the tables
The issue with this query is that is displays the row counts in a random order that doesn't correspond with the order of the tables in the query, and so I don't know which row count goes with which table - hence why I need both the table names and row counts.
Simply add the names of the tables as literals in your queries:
SELECT 'table_name' AS table_name, COUNT(*) AS row_count FROM table_name
UNION ALL
SELECT 'table_name2' AS table_name, COUNT(*) AS row_count FROM table_name2
UNION ALL
…
The following query generates the UNION query to produce counts of all records.
The problem to solve is that (as of December 2022) INFORMATION_SCHEMA.TABLES incorrectly defines every table and view as a BASE TABLE so you will need some logic to eliminate the views.
In Data Warehousing it is common practise to record snapshots of the record counts of landing tables at frequent intervals. Any unexpected deviations from expected counts can be used for reporting/alerting
WITH Table_List AS (
SELECT table_schema,table_name, CONCAT('SELECT CURRENT_DATE AS run_date, ''',table_name, ''' AS table_name, COUNT(*) AS Records FROM "',table_schema,'"."', table_name, '"') AS BaseSQL
FROM INFORMATION_SCHEMA.TABLES
WHERE
table_schema = 'YOUR_DB_NAME' -- Change this
AND table_name LIKE 'YOUR TABLE PATTERN%' -- Change or remove this line
)
, Total_Records AS (
SELECT COUNT(*) AS Table_Count
FROM Table_List
)
SELECT
CASE WHEN ROW_NUMBER() OVER (ORDER BY table_name) = Table_Count
THEN BaseSQL
ELSE CONCAT(BaseSql, ' UNION ALL') END AS All_Table_Record_count_SQL
FROM Table_List CROSS JOIN Total_Records
ORDER BY table_name;
I need to update a second table with the results of this query:
SELECT Tag, battery, Wearlevel, SensorTime
FROM (
SELECT m.* , ROW_NUMBER() OVER (PARTITION BY TAG ORDER BY SensorTime DESC) AS rn
FROM [dbo].[TELE] m
) m2
where m2.rn = 1;
But. I had a hard time fixing the SET without messing it up. I want to have a table which has all data from last date of each TAG without duplicates.
Below code maybe you want.
UPDATE
Table_A
SET
Table_A.Primarykey = 'ss'+Table_B.Primarykey,
Table_A.AddTime = 'jason_'+Table_B.AddTime
FROM
Test AS Table_A
INNER JOIN UsersInfo AS Table_B
ON Table_A.id = Table_B.id
WHERE
Table_A.Primarykey = '559713e6-0d85-4fe7-87a4-e9ceb22abdcf'
For more details, you also can refer below posts and blogs.
1. How do I UPDATE from a SELECT in SQL Server?
2. How to UPDATE from SELECT in SQL Server
I am trying to do a left ourter join in Athena and my query looks like the following:
SELECT customer.name, orders.price
FROM customer LEFT OUTER JOIN order
ON customer.id = orders.customer_id
WHERE price IS NULL;
Where each customer could only have one order in the orders table at most and there are customers with no order in the orders table at all. So I am expecting to get some number of records where there is a customer in the customer table with no records in orders table which means when I do LEFT OUTER JOIN the price will be NULL. But this query returns 0 every time I run it. I have queries both tables separately and pretty sure there is data in both but not sure why this is returning zero where it works if I remove the price IS NULL. I have also tried price = '' and price IN ('') and none of them works. Has anyone here had a similar experience before? Or is there something wrong with my query that I can not see or identify?
It seems that your query is correct. To validate, I created two CTEs that should match up with your customer and orders table and ran your query against them. When running the query below, it returns a record for customer 3 Ted Johnson who did not have an order.
WITH customer AS (
SELECT 1 AS id, 'John Doe' AS name
UNION
SELECT 2 AS id, 'Jane Smith' AS name
UNION
SELECT 3 AS id, 'Ted Johnson' AS name
),
orders AS (
SELECT 1 AS customer_id, 20 AS price
UNION
SELECT 2 AS customer_id, 15 AS price
)
SELECT customer.name, orders.price
FROM customer LEFT OUTER JOIN orders
ON customer.id = orders.customer_id
WHERE price IS NULL;
I'd suggest running the following queries:
COUNT(DISTINCT id) FROM customers;
COUNT(DISTINCT customer_id) FROM orders;
Based on the results you are seeing, I would expect those counts to match. Perhaps your system is creating a record in the orders table whenever a customer is created with a price of 0.
Probably you can't use where for order table.
SELECT customer.name, order.price
FROM customer LEFT OUTER JOIN order
ON customer.id = orders.customer_id AND order.price IS NULL;
I have a recordset named rsProductClass that is returned from a table in the database. It is a very simple SELECT * FROM Table WHERE ProductID = {ID Value Here} and the table is like this:
ProductID | UPPERTIER | LOWERTIER | NATIER | OTHERTIER
1 20 60 10 10
2 10 90 NULL NULL
3 NULL 40 NULL 5
The table may or may not have a value for each of the various tiers.
What I want to do is show to the user which column has the highest value and what the name of that column is. So for example, if you were looking at ProductID 2, then the page should display "This is likely to be a LOWERTIER product"
I need to sort the rsProductClass query in such a way that it returns me a list of columns in that query ordered by the value in each column. I want to treat the NULL values as zeros.
I tried to mess about with doing valuelist() and some ArrayToList() type functions but it crashes on the NULL values. Say I add columns to an array, and then use ArraySort() to get them in some kind of order, I'll get an error saying something like "Position 1 is not numeric" because it has a NULL value.
Is this something that can be done by ColdFusion? I suppose its some sort of pivoting of the recordset which is beyond my ability.
Something like this would work:
<cfquery name="tiers" datasource="...">
SELECT ProductID, UPPERTIER VALUE, 'UPPERTIER' TIER
WHERE UPPERTIER IS NOT NULL
UNION
SELECT ProductID, LOWERTIER VALUE, 'LOWERTIER' TIER
WHERE LOWERTIER IS NOT NULL
UNION
SELECT ProductID, OTHERTIER VALUE, 'OTHERTIER' TIER
WHERE OTHERTIER IS NOT NULL
UNION
SELECT ProductID, NATIER VALUE, 'NATIER' TIER
WHERE NATIER IS NOT NULL
ORDER BY ProductID, VALUE
</cfquery>
<cfset productGroup = StructNew()>
<cfoutput query="tiers" group="ProductID">
<cfset productGroup[ProductID].TIER = TIER>
<cfset productGroup[ProductID].VALUE = VALUE>
</cfoutput>
<cfdump var="#productGroup#">
Starting with ColdFusion 10 you can use <cfloop query="..." group="...">, before that <cfoutput> must be used.
If you're willing to unpivot your query, you might do something like the following. I used COALESCE() instead of ISNULL() (either one works in this situation, but COALESCE() is the ANSI standard). The column tier_rank will give the rank of the given tier -- that is, the tier with the highest value will have a rank of 1. If there are two tiers that both have the highest value, then both will have a value in tier_rank of 1 (this is why you would use RANK() instead of ROW_NUMBER() -- you could also use DENSE_RANK() if it better fits your requirements):
SELECT p1.product_id, p1.tier_name, p1.tier_value
, RANK() OVER ( PARTITION BY p1.product_id ORDER BY p1.tier_value DESC ) tier_rank
FROM (
SELECT product_id, 'UPPERTIER' AS tier_name
, COALESCE(uppertier, 0) AS tier_value
FROM products
UNION ALL
SELECT product_id, 'LOWERTIER' AS tier_name
, COALESCE(lowertier, 0) AS tier_value
FROM products
UNION ALL
SELECT product_id, 'NATIER' AS tier_name
, COALESCE(natier, 0) AS tier_value
FROM products
UNION ALL
SELECT product_id, 'OTHERTIER' AS tier_name
, COALESCE(othertier, 0) AS tier_value
FROM products
) p1
Please see SQL Fiddle demo here.
It might be possible to re-pivot the above unpivoted query, but I must admit my attempts at doing so failed.
I had to do something similar to this recently and looked into UNPIVOT in SQL Server. Going with the suggestion to Unpivot your query like David said, you could do something like this. This doesn't add RANK column, but it does order the values.
SELECT ProductID, Tier, TierValue
FROM
(SELECT ProductID, ISNULL(UpperTier,0) UpperTier, ISNULL(LowerTier,0) LowerTier, ISNULL(NaTier,0) NaTier, ISNULL(OtherTier,0) OtherTier
FROM products) p
UNPIVOT
(TierValue FOR Tier IN
(UpperTier, LowerTier, NaTier, OtherTier)
)AS unpvt
ORDER BY ProductID, TierValue Desc
SQL FIDDLE