Count query giving wrong column name error - sql

select COUNT(analysed) from Results where analysed="True"
I want to display count of rows in which analysed value is true.
However, my query gives the error: "The multi-part identifier "Results.runId" could not be bound.".
This is the actual query:
select ((SELECT COUNT(*) AS 'Count'
FROM Results
WHERE Analysed = 'True')/failCount) as PercentAnalysed
from Runs
where Runs.runId=Analysed.runId
My table schema is:
The value I want for a particular runId is: (the number of entries where analysed=true)/failCount
EDIT : How to merge these two queries?
i) select runId,Runs.prodId,prodDate,prodName,buildNumber,totalCount as TotalTestCases,(passCount*100)/(passCount+failCount) as PassPercent,
passCount,failCount,runOwner from Runs,Product where Runs.prodId=Product.prodId
ii) select (cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
I tried this :
select runId,Runs.prodId,prodDate,prodName,buildNumber,totalCount as TotalTestCases,(passCount*100)/(passCount+failCount) as PassPercent,
passCount,failCount,runOwner,counts.runId,(cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs,Product
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
where Runs.prodId=Product.prodId
but it gives error.

Your problems are arising from improper joining of tables. You need information from both Runs and Results, but they aren't combined properly in your query. You have the right idea with a nested subquery, but it's in the wrong spot. You're also referencing the Analysed table in the outer where clause, but it hasn't been included in the from clause.
Try this instead:
select (cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
I've set this up as an inner join to eliminate any runs which don't have analysed results; you can change it to a left join if you want those rows, but will need to add code to handle the null case. I've also added casts to the two numbers, because otherwise the query will perform integer division and truncate any fractional amounts.

I'd try the following query:
SELECT COUNT(*) AS 'Count'
FROM Results
WHERE Analysed = 'True'
This will count all of your rows where Analysed is 'True'. This should work if the datatype of your Analysed column is either BIT (Boolean) or STRING(VARCHAR, NVARCHAR).

Use CASE in Count
SELECT COUNT(CASE WHEN analysed='True' THEN analysed END) [COUNT]
FROM Results
Click here to view result

select COUNT(*) from Results where analysed="True"

Related

TSQL "where ... group by ..." issue that needs solution like "having ..."

I have 3 sub-tables of different formats joined together with unions if this affects anything into full-table. There I have columns "location", "amount" and "time". Then to keep generality for my later needs I union full-table with location-table that has all possible "location" values and other fields are null into master-table.
I query master-table,
select location, sum(amount)
from master-table
where (time...)
group by location
However some "location" values are dropped because sum(amount) is 0 for those "location"s but I really want to have full list of those "location"s for my further steps.
Alternative would be to use HAVING clause but from what I understand HAVING is impossible here because i filter on "time" while grouping on "location" and I would need to add "time" in grouping which destroys the purpose. Keep in mind that the goal here is to get sum(amount) in each "location"
select location, sum(amount)
from master-table
group by location, time
having (time...)
To view the output:
with the first code I get
loc1, 5
loc3, 10
loc6, 1
but I want to get
loc1, 5
loc2, 0
loc3, 10
loc4, 0
loc5, 0
loc6, 1
Any suggestions on what can be done with this structure of master-table? Alternative solution to which I have no idea how to code would be to add numbers from the first query result to location-table (as a query, not actual table) with the final result query that I've posted above.
What you want will require a complete list of locations, then a left-outer join using that table and your calculated values, and IsNull (for tsql) to ensure you see the 0s you expect. You can do this with some CTEs, which I find valuable for clarity during development, or you can work on "putting it all together" in a more traditional SELECT...FROM... statement. The CTE approach might look like this:
WITH loc AS (
SELECT DISTINCT LocationID
FROM location_table
), summary_data as (
SELECT LocationID, SUM(amount) AS location_sum
FROM master-table
GROUP BY LocationID
)
SELECT loc.LocationID, IsNull(location_sum,0) AS location_sum
FROM loc
LEFT OUTER JOIN summary_data ON loc.LocationID = summary_data.LocationID
See if that gets you a step or two closer to the results you're looking for.
I can think of 2 options:
You could move the WHERE to a CASE WHEN construction:
-- Option 1
select
location,
sum(CASE WHEN time <'16:00' THEN amount ELSE 0 END)
from master_table
group by location
Or you could JOIN with the possible values of location (which is my first ever RIGHT JOIN in a very long time 😉):
-- Option 2
select
x.location,
sum(CASE WHEN m.time <'16:00' THEN m.amount ELSE 0 END)
from master_table m
right join (select distinct location from master_table) x ON x.location = m.location
group by x.location
see: DBFIDDLE
The version using T-SQL without CTEs would be:
SELECT l.location ,
ISNULL(m.location_sum, 0) as location_sum
FROM master-table l
LEFT JOIN (
SELECT location,
SUM(amount) as location_sum
FROM master-table
WHERE (time ... )
GROUP BY location
) m ON l.location = m.location
This assumes that you still have your initial UNION in place that ensures that master-table has all possible locations included.
It is the where clause that excludes some locations. To ensure you retain every location you could introduce "conditional aggregation" instead of using the where clause: e.g.
select location, sum(case when (time...) then amount else 0 end) as location_sum
from master-table
group by location
i.e. instead of excluding some rows from the result, place the conditions inside the sum function that equate to the conditions you would have used in the where clause. If those conditions are true, then it will aggregate the amount, but if the conditions evaluate to false then 0 is summed, but the location is retained in the result.

Is there a way to use DISTINCT and COUNT(*) together to bulletproof your code against DUPLICATE entries?

I got help with a function yesterday to correctly get the count of multiple items in a column based on multiple criteria/columns. However, if there is a way to get the DISTINCT count of all the entries in the table based on aggregated GROUP BY statement.
SELECT TIME = ap.day,
acms.tenantId,
acms.CallingService,
policyList = ltrim(sp.value),
policyInstanceList = ltrim(dp.value),
COUNT(*) AS DISTINCTCount
FROM dbo.acms_data acms
CROSS APPLY string_split(acms.policyList, ',') sp
CROSS APPLY string_split(acms.policyInstanceList, ',') dp
CROSS APPLY (select day = convert(date, acms.[Time])) ap
GROUP BY ap.day, acms.tenantId, sp.value, dp.value, acms.CallingService
I would just like to know if there would be a way to see if there is a workaround for using DISTINCT and Count(*) together and whether or not it would affect my results to make this algorithm potentially invulnerable to duplicate entries.
The reason why I have to use COUNT(*) is because I am aggregating based on every column in the table not just a specific column or multiple.
We can use DISTINCT with COUNT together like this example.
USE AdventureWorks2012
GO
-- This query shows 290 JobTitle
SELECT COUNT(JobTitle) Total_JobTitle
FROM [HumanResources].[Employee]
GO
-- This query shows only 67 JobTitle
SELECT COUNT( DISTINCT JobTitle) Total_Distinct_JobTitle
FROM [HumanResources].[Employee]
GO

subquerying in WHERE/Joining 3 tables, 2 for records and one for number, returns no result/fails - MSAccess

My query does return any records. Depending on how I write it, it returns no records or all records, although I don't have the code that just returned everything.
I need to pull data from two sources with actual records, and a third table which has project-wide information not specific to any records. I need to filter out records which are greater than the Miles_Budgeted variable.
This returns no records, although if I replaces param.Miles_Budgeted with a numeric value e.g. 1000, it filters to the desired records.
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.cpminrmd,
a.RunTotMiles,
param.Miles_Budgeted
FROM
(SELECT (p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Miles_Budgeted FROM Tbl_Project_Parameters as p) AS param,
qry_par_l2_by_cpermi AS a
INNER JOIN
qry_l2 AS b
ON a.l1l2 = b.l1l2
WHERE
((a.RunTotMiles) <=
(Param.Miles_Budgeted
)
)
ORDER BY
a.sort_id;
This variant of the query does not run (Syntax Error in FROM Clause)
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.cpminrmd,
a.runtotmiles,
param.miles_budgeted
FROM (
(
SELECT (p.budget_cost_targ / p.project_cost_per_mi) AS miles_budgeted
FROM tbl_project_parameters AS p ) AS param
INNER JOIN qry_par_l2_by_cpermi AS a )
INNER JOIN qry_l2 AS b
ON a.l1l2 = b.l1l2
AND (
a.runtotmiles) <= ( param.miles_budgeted )
ORDER BY a.sort_id;
This also returns no records:
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.RunTotMiles,
a.cpminrmd
FROM
qry_par_l2_by_cmipermi AS a
INNER JOIN
qry_l2 AS b
ON a.l1l2 = b.l1l2
WHERE
(
((a.RunTotMiles) <=
(
SELECT
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p
)
)
)
ORDER BY
a.sort_id;
Again, if
SELECT
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p
is replaces with a numeric value, the query returns the correct records. I have tried surrounding the subq or field with val() or Format(,"Standard") but this does not see to fix the issue; a separate query with just the relevant code returns the correct Budgeted_Miles as 1000 as it should.
Any thoughts appreciated.
Have you tried limiting that subquery to return only one record? I know some versions of SQL don't like when you try comparing the results of a SELECT to a single value.
I believe the syntax for MS Access would use "TOP":
SELECT TOP 1
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p

ORA-01427: single-row subquery returns more than one row error comes after fetching some records

My query is fetching records in sql developer. But when i run it from ksh file and spool it, partial records get generates and error comes. How can I find out the data for which this error is coming?
Query is:
select im.item as "ITEM",
(select val.uda_value_desc
from uda_values val,UDA_ITEM_LOV lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and lov.UDA_VALUE=val.UDA_VALUE
and val.uda_id=3) as "SERIE",
(select val.uda_value_desc
from uda_values val, UDA_ITEM_date lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and val.uda_id=20) as "UDA_DATE"
from ahl_rumm_prod_item_master im;
table ahl_rumm_prod_item_master has 313535 records.
One way that make minimal changes to your code is to change your correlated sub-queries to SELECT COUNT( ... ) FROM ... and then filter out the rows where something other than one result is returned:
SELECT *
FROM (
select im.item as "ITEM",
(select COUNT( val.uda_value_desc )
from uda_values val,
UDA_ITEM_LOV lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and lov.UDA_VALUE=val.UDA_VALUE
and val.uda_id=3
) as "SERIE",
(select COUNT( val.uda_value_desc )
from uda_values val,
UDA_ITEM_date lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and val.uda_id=20
) as "UDA_DATE"
from ahl_rumm_prod_item_master im
)
WHERE SERIE <> 1
OR UDA_DATE <> 1;
This will tell you the items where errors are occurring and you can investigate further.
One or both of your inner query return more than 1 row. therefore It cannot be set as a column value. What you should do is add some conditions to the inner queries to make sure that they return just one row

Duplicate results returned from query when distinct is used

On a current project at I am needing to do some pagination of results returned from SQL. I have hit a corner case in which the query can accept identifiers as part of the where clause, normally this isn't an issue but in one case we have a single identifier being passed up that has a one to many relationship with one of the tables that the query joins on and it is returning multiple rows in the results. That issue was fixed by introducing a distinct to the query. The following is the query which returns the correct result of one row (all table/field names have been changed of course):
select distinct [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
However when I introduce pagination into the query I am finding that it is now returning multiple rows when it should be only be returning one. The method I am using for pagination is as follows:
select [item_id]
from (
select distinct [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
) as [items]
where [items].[row_num] between 0 and 100
I worry that adding a distinct to the outer query will cause an incorrect number of results to be returned and I am unsure of how else to fix this issue. The database I am querying is MS SQL Server 2008.
About 5 minutes after posting the question a possible solution hit me, if I group by the item_id (and any sort criteria) which should only be one instance of it should solve the issue. After testing this was the query that I was left with:
select [item_id]
from (
select [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
group by [item_table].[item_id], [item_table].[pub_date]
) as [items]
where [items].[row_num] between 0 and 100
I don't see where the DISTINCT is adding any value in your first query. The results are [item_table].[item_id] and [row_num]. Because the value of [row_num] is already distinct, the combination of [item_table].[item_id] and [row_num] will be distinct. When adding the DISTINCT keyword to the query, no rows are excluded.
In the second query, your results will return [item_id] from the sub query where [row_num] meets the criteria. If there where duplicate [item_id] values in the sub-query, there will be duplicates in the final results, but now you don't display [row_num] to distinguish the duplicates.