access select distinct on certain column - sql

I have a table with some search results. The search results maybe repeated because each result may be found using a different metric. I want to then query this table select only the distinct results using the ID column. So to summarize I have a table with an ID column but the IDs may be repeated and I want to select only one of each ID with MS Access SQL, how should I go about doing this?
Ok I have some more info after trying a couple of the suggestions. The Mins, and Maxes won't work because the column they are operating on cannot be shown. I get an error like You tried to execute a query that does not include the specified expression... I now have all my data sorted, here is what it looks like
ID|Description|searchScore
97 test 1
97 test .95
120 ball .94
97 test .8
120 ball .7
so the problem is that since the rows were put into the table using different search criteria I have duplicated rows with different scores. What I want to do is select only one of each ID sorted by the searchScore descending. Any ideas?

SELECT DISTINCT ID
FROM Search_Table;
Based on the last update to your question, the following query seems appropriate.
SELECT ID, [Description], Max(searchScore)
FROM Search_Table
GROUP BY ID, [Description];
However that's nearly the same as Gordon's suggestion from yesterday, so I'm unsure whether this is what you want.

Here is a way where you can get one of the search criteria:
select id, min(search_criteria)
from t
group by id
This will always return the first one alphabetically. You can also easily get the last one using max().
You could also use:
select id, first(search_criteria)
from t
group by id

Related

Why ORDER BY works only when I gave an alias name for the column, but didn't work just as column name?

This code cannot be executed, showed an error like
column "o.total_amt_usd" must appear in the GROUP BY clause or be used in an aggregate function
SELECT a.name, MIN(o.total_amt_usd)
FROM accounts a
JOIN orders o ON a.id = o.account_id
GROUP BY a.name
ORDER BY o.total_amt_usd
LIMIT 3
But after I use an alias, it worked:
SELECT a.name, MIN(o.total_amt_usd) small
FROM accounts a
JOIN orders o ON a.id = o.account_id
GROUP BY a.name
ORDER BY small
LIMIT 3
Could anybody explain a little bit about this, please?
Both logically make sense to me. But one of them is not working.
Thanks a lot.
You can't order by o.total_amt_usd since it's not available in the result set (after grouping on name).
You need to order by a grouped field or using an aggregate function like MIN. In this case you'll want to order by MIN(o.total_amt_usd) which is essentially what you are doing after using the alias in the order-clause.
Think about what you're asking of the first query and perhaps try a visual example by hand.
Imagine a table with just 4 rows, John has two rows with amounts of 50 and 20, Bob has two rows with amounts of 30 and 60.
You are asking for each unique name and the corresponding minimum amount, so the results are naturally John:20, Bob:30.
By asking to order your results by referring specfically to every row's Total (and not the aggregated total) you are saying, order my two rows by looking at all four rows, which means John could go both before Bob and after Bob given 20 is less than 30 and 50 is greater than 30.
You might look at the data visually and see the "correct" order, however for the query engine this makes no sense, you can only prioritise the resulting two rows based on their aggregated values, therefore you must order by those aggregated values, either using that column's alias or using the same expression. You cannot order by non-aggregated columns.

Validate that only one value exists

I have a table with two relevant columns. I'll call them EID and MID. They are not unique.
In theory, if the data is set up correctly, there will be many records for each EID and every one of those records should have the same MID.
There are situations where someone may manually update data incorrectly and I need to be able to quickly identify if there is a second MID for any EID.
Ideally, I'd have a query that returns how many MIDs for each EID, but only showing results where there is more than 1 MID. Below is what I'd like the results to look like.
EID Count of Distinct MID values
200345 2
304334 3
I've tried several different forms of queries, but I can't seem to figure out how to reach this result. We're on SQL Server.
You can use the following using COUNT with DISTINCT and HAVING:
SELECT EID, COUNT(DISTINCT MID)
FROM table_name
GROUP BY EID
HAVING COUNT(DISTINCT MID) > 1
demo on dbfiddle.uk

ORDER BY an aggregated column in Report Builder 3.0

On a report builder 3.0, i retreived some items and counted them using a Count aggregate. Now i want to order them from highest to lowest. How do i use the ORDER BY function on the aggregated column? The picture below show the a column that i want to ORDER BY it, it is ticked.
Pic
The code is vers simple as shown bellow:
SELECT DISTINCT act_id,NameOfAct,
FROM Acts
Your picture indicates you also want a Total row at the bottom:
SELECT
COALESCE(NameOfAct,'Total') NameOfAct,
COUNT(DISTINCT act_id) c
FROM Acts
GROUP BY ROLLUP(NameOfAct)
ORDER BY
CASE WHEN NameOfAct is null THEN 1 ELSE 0 END,
c DESC;
Result of example data:
NameOfAct count
-------------- -------
Act_B 3
Act_A 2
Act_Z 1
Total 6
Try it with example rows at: http://sqlfiddle.com/#!18/dbd6c/2
I looked at the Pic. So you might have duplicate acts with the same name. And you want to know the number of acts that have the same unique name.
You might want to group the results by name:
GROUP BY NameOfAct
And include the act names and their counts in the query results:
SELECT NameOfAct, COUNT(*) AS ActCount
(Since the act_id column is not included in the groups, you need to omit it in the SELECT. The DISTINCT is also not necessary anymore, since all groups are unique already.)
Finally, you can sort the data (probably descending to get the acts with the largest count on top):
ORDER BY ActCount DESC
Your complete query would become something like this:
SELECT NameOfAct, COUNT(*) AS ActCount
FROM Acts
GROUP BY NameOfAct
ORDER BY ActCount DESC
Edit:
By the way, you use field "act_id" in your SELECT clause. That's somewhat confusing. If you want to know counts, you want to look at either the complete table data or group the table data into smaller groups (with the GROUP BY clause). Then you can use aggregate functions to get more information about those groups (or the whole table), like counts, average values, minima, maxima...
Single record information, like an act's ID in your case, is typically not important if you want to use statistic/aggregate methods on grouped data. Suppose your query returns an act name which is used 10 times. Then you have 10 records in your table, each with a unique act_id, but with the same name.
If you need just one act_id that represents each group / act name (and assuming act_id is an autonumbering field), you might include the latest / largest act_id value in the query using the MAX aggregate function:
SELECT NameOfAct, COUNT(*) AS ActCount, MAX(act_id) AS LatestActId
(The rest of the query remains the same.)

Combine multiple date fields into one on query

I have a requirement to create a report that counts a total from 2 date fields into one. A simplified example of the table I'm querying is:
ID, FirstName, LastName, InitialApplicationDate, UpdatedApplicationDate
I need to query the two date fields in a way that creates similar output to the following:
Date | TotalApplications
I would need the date output to include both InitialApplicationDate and
UpdatedApplicationDate fields and the TotalApplications output to be a count of the total for both types of date fields. Originally I thought maybe a Union would work however that returns 2 separate records for each date. Any ideas how I might accomplish this?
The simplest way, I think, is to unpivot using apply and then aggregate:
select v.thedate, count(*)
from t cross apply
(values (InitialApplicationDate), (UpdatedApplicationDate)) v(thedate)
group by v.thedate;
You might want to add where thedate is not null if either column could be NULL.
Note that the above will count the same application twice, once for each date. That appears to be your intention.

SQL SUM function with added

total novice here with SQL SUM function question. So, SUM function itself works as I expected it to:
select ID, sum(amount)
from table1
group by ID
There are several records for each ID and my goal is to summarize each ID on one row where the next column would give me the summarized amount of column AMOUNT.
This works fine, however I also need to filter out based on certain criteria in the summarized amount field. I.e. only look for results where the summarized amount is either bigger, smaller or between certain number.
This is the part I'm struggling with, as I can't seem to use column AMOUNT, as this messes up summarizing results.
Column name for summarized results is shown as "00002", however using this in the between or > / < clause does not work either. Tried this:
select ID, sum(amount)
from table1
where 00002 > 1000
group by ID
No error message, just blank result, however plenty of summarized results with values over 1000.
Unfortunately not sure on the engine the database runs on, however it should be some IBM-based product.
The WHERE clause will filter individual rows that don't match the condition before aggregating them.
If you want to do post aggregation filtering you need to use the HAVING Clause.
HAVING will apply the filter to the results after being grouped.
select ID, sum(amount)
from table1
group by ID
having sum(amount) > 1000