How to use DISTINCT in ms access? - sql

I have the following query:
SELECT DISTINCT AwardDescriptions.aID, CostCentres.cCC
FROM AwardDescriptions
INNER JOIN CostCentres ON AwardDescriptions.aID = CostCentres.cNumber
ORDER BY CostCentres.cCC;
For some reason, when I run my query, it still shows all duplicate values.
Any suggestions?

You can use group by and get either the minimum or maximum value:
SELECT MAX(AwardDescriptions.aID) as aID, CostCentres.cCC
FROM AwardDescriptions INNER JOIN
CostCentres
ON AwardDescriptions.aID = CostCentres.cNumber
GROUP BY CostCentres.cCC
ORDER BY CostCentres.cCC;

Related

Oracle SQL - how to NOT SHOW athlete name that apears only once

created a view called winners, it contains the columns: athlete_name,year,medal_won
its basicly athletes that won olympic medal and the year,
it look like that,
data base is in live sql: https://livesql.oracle.com/apex/f?p=590:1000:0
select distinct year,athlete_name,medal
from olym.olym_medals
join olym.olym_athlete_games on olym_athlete_games.id = olym_medals.athlete_game_id
join olym.olym_nations on olym_nations.id = olym_athlete_games.nation_id
join olym.olym_games on olym_games.id = Olym_athlete_games.game_id
join olym.olym_athletes on olym_athletes.id = olym_athlete_games.athlete_id
order by athlete_name
as you can see some name show only once and some names are showing more than once, i want to get rid off all lines of those who show ONLY ONCE, please help me.
thank you!
if i have understand your problem, must group your data,
select year,athlete_name,medal, count(*) "number of Medals"
from olym.olym_medals
join olym.olym_athlete_games on olym_athlete_games.id = olym_medals.athlete_game_id
join olym.olym_nations on olym_nations.id = olym_athlete_games.nation_id
join olym.olym_games on olym_games.id = Olym_athlete_games.game_id
join olym.olym_athletes on olym_athletes.id = olym_athlete_games.athlete_id
group by year,athlete_name,medal;
If I followed you correctly, you can use window functions:
select *
from (
select og.year, oa.athlete_name, om.medal, count(*) over(partition by oa.id) cnt
from olym.olym_medals om
join olym.olym_athlete_games oag on oag.id = om.athlete_game_id
join olym.olym_nations ona on ona.id = oag.nation_id
join olym.olym_games og on og.id = oag.game_id
join olym.olym_athletes oa on oa.id = oag.athlete_id
) t
where cnt > 1
order by athlete_name
Notes:
I am unsure why you were using distinct in the first place, so I removed it (I suspect it is actually not needed)
I added table aliases to shorten the query, and prefixed the columns in the select clause with the table they belong to (you might want to review that) - these are best practices when dealing with multi-table queries
Use GROUP BY and HAVING COUNT(*) > 1:
SELECT year,
athlete_name,
medal
FROM olym.olym_medals
INNER JOIN olym.olym_athlete_games
ON olym_athlete_games.id = olym_medals.athlete_game_id
INNER JOIN olym.olym_nations
ON olym_nations.id = olym_athlete_games.nation_id
INNER JOIN olym.olym_games
ON olym_games.id = Olym_athlete_games.game_id
INNER JOIN olym.olym_athletes
ON olym_athletes.id = olym_athlete_games.athlete_id
GROUP BY
year,
athlete_name,
medal
HAVING COUNT(*) > 1
ORDER BY athlete_name

SQL Count uses info from join

I need to count the amount of times InternalMenuLinkItemNumber appears per sitenumber and per order mode. Then i need to show MenuItemID and i do that with a inner join using item numbers, but when i add this join it skews the QTY result. I've tried using distinct in the COUNT but then all the QTY is 1. Please assist.
Query and result where QTY result is 100% correct but no MenuItemID.
SELECT ST_Sites.BusinessUnit,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,InternalMenuLinkItemNumber,[ST_SalesMix].MenuItemID,OrderMode,SellingPrice,COUNT(ST_SalesMixTransactions_RealTimeFeed.InternalMenuLinkItemNumber) as QTY
FROM ST_AlohaSalesMixTransactions_RealTimeFeed
inner join ST_Sites on ST_Sites.SiteNumber= [ST_SalesMixTransactions_RealTimeFeed].SiteNumber
where [ST_SalesMixTransactions_RealTimeFeed].BusinessDate between'2017-06-27'and'2017-07-03' and [ST_SalesMixTransactions_RealTimeFeed].SiteNumber = '1001006'
group by InternalMenuLinkItemNumber,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,OrderMode,SellingPrice,ST_Sites.BusinessUnit,[ST_SalesMix].MenuItemID
order by InternalMenuLinkItemNumber
Result where QTY comes out as expected:
If I add the inner join to get MenuItemID:
Query:
SELECT ST_Sites.BusinessUnit,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,InternalMenuLinkItemNumber,[ST_SalesMix].MenuItemID,OrderMode,SellingPrice,COUNT(ST_SalesMixTransactions_RealTimeFeed.InternalMenuLinkItemNumber) as QTY
FROM ST_AlohaSalesMixTransactions_RealTimeFeed
inner join ST_SalesMix on [ST_AlohaSalesMixTransactions_RealTimeFeed].InternalMenuLinkItemNumber= ST_SalesMix.ItemNumber
inner join ST_Sites on ST_Sites.SiteNumber= [ST_SalesMixTransactions_RealTimeFeed].SiteNumber
where [ST_SalesMixTransactions_RealTimeFeed].BusinessDate between'2017-06-27'and'2017-07-03' and [ST_SalesMixTransactions_RealTimeFeed].SiteNumber = '1001006'
group by InternalMenuLinkItemNumber,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,OrderMode,SellingPrice,ST_Sites.BusinessUnit,[ST_SalesMix].MenuItemID
order by InternalMenuLinkItemNumber
Result where QTY is now way off:
If I use distinct:
Query:
SELECT ST_Sites.BusinessUnit,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,InternalMenuLinkItemNumber,[ST_SalesMix].MenuItemID,OrderMode,SellingPrice,COUNT(distinct ST_SalesMixTransactions_RealTimeFeed.InternalMenuLinkItemNumber) as QTY
FROM ST_AlohaSalesMixTransactions_RealTimeFeed
inner join ST_SalesMix on [ST_AlohaSalesMixTransactions_RealTimeFeed].InternalMenuLinkItemNumber= ST_SalesMix.ItemNumber
inner join ST_Sites on ST_Sites.SiteNumber= [ST_SalesMixTransactions_RealTimeFeed].SiteNumber
where [ST_SalesMixTransactions_RealTimeFeed].BusinessDate between'2017-06-27'and'2017-07-03' and [ST_SalesMixTransactions_RealTimeFeed].SiteNumber = '1001006'
group by InternalMenuLinkItemNumber,[ST_SalesMixTransactions_RealTimeFeed].SiteNumber,OrderMode,SellingPrice,ST_Sites.BusinessUnit,[ST_SalesMix].MenuItemID
order by InternalMenuLinkItemNumber
Result for QTY is now all 1:
If I understand correctly, you want something like
SELECT SiteNumber, OrderMode, count([DISTINCT?] InternalMenuLinkItemNumber)
...
GROUP BY SiteNumber, OrderMode
You want to count the InternalMenuLinkItemNumber, so InternalMenuLinkItemNumber must not occur in the GROUP BY clause.
EDIT:
When using GROUP BY, the SELECT list may only contain columns also mentioned in the GROUP BY clause, or aggregate functions (on arbitrary columns).
Try this:
SELECT a.InternalMenuLinkItemNumber, a.SiteNumber, a.OrderMode, a.SellingPrice, a.BusinessUnit, a.MenuItemID, a.QTY, CASE WHEN MAX(b.MenuItemID) = MIN(b.MenuItemID) THEN MAX(b.MenuItemID) ELSE -1 END AS MenuItemID
FROM
(SELECT ST_Sites.BusinessUnit, [ST_SalesMixTransactions_RealTimeFeed].SiteNumber, InternalMenuLinkItemNumber, [ST_SalesMix].MenuItemID, OrderMode, SellingPrice, COUNT(ST_SalesMixTransactions_RealTimeFeed.InternalMenuLinkItemNumber) as QTY
FROM ST_AlohaSalesMixTransactions_RealTimeFeed
INNER JOIN ST_Sites on ST_Sites.SiteNumber = [ST_SalesMixTransactions_RealTimeFeed].SiteNumber
WHERE [ST_SalesMixTransactions_RealTimeFeed].BusinessDate between'2017-06-27'and'2017-07-03' and [ST_SalesMixTransactions_RealTimeFeed].SiteNumber = '1001006'
GROUP BY InternalMenuLinkItemNumber, [ST_SalesMixTransactions_RealTimeFeed].SiteNumber, OrderMode, SellingPrice, ST_Sites.BusinessUnit, [ST_SalesMix].MenuItemID
) a
INNER JOIN ST_SalesMix b ON a.InternalMenuLinkItemNumber = b.ItemNumber
GROUP BY a.InternalMenuLinkItemNumber, a.SiteNumber, a.OrderMode, a.SellingPrice, a.BusinessUnit, a.MenuItemID, a.QTY
ORDER BY a.InternalMenuLinkItemNumber
It works on the theory that your first query gives good counts, so keep that as it is (it's now the inner query) and then do the problematic join outside of it. Obviously there are many rows from ST_SalesMix for each properly counted row in the first query, so I'm grouping on the original group list but that means that you might get multiple MenuItemIDs. I'm checking for that in the CASE statement by testing the MAX and MIN MenuItemIDs - if they are the same return MAX(MenuItemID) otherwise I'm returning -1 as an error flag to indicate that there were multiple MenuItemIDs associated with this group. It might not be the most efficient method but I didn't have much to go on.
I hope this helps.
all is sorted now. Thanks to everyone.
#jwolf your suggested query was the answer.

Calculation from two queries in SQL

I have 2 queries that give me counts. I want to divide one count by the other - I currently have the below SQL but throws out errors immediately:
SELECT tbl_CEAR_Name.CEAR_Team,
Q_Manager_Backlog_Total.Backlogs,
Q_Manager_CHS_Total.CHS_Total,
[Q_manager_CHS_Total].[CHS_Total]/[q_managers_backlog_total].[backlogs] AS Expr1
FROM Q_Manager_CHS_Total
INNER JOIN
(
Q_Manager_Backlog_Total
INNER JOIN tbl_CEAR_Name
ON Q_Manager_Backlog_Total.CEAR_Team = tbl_CEAR_Name.CEAR_Team
)
ON Q_Manager_CHS_Total.CEAR_Team = tbl_CEAR_Name.CEAR_Team
ORDER BY Q_Manager_Backlog_Total.Backlogs DESC;
You totally banjaxed your joins... Try this
SELECT tbl_CEAR_Name.CEAR_Team,
Q_Manager_Backlog_Total.Backlogs,
Q_Manager_CHS_Total.CHS_Total,
[Q_manager_CHS_Total].[CHS_Total]/[q_managers_backlog_total].[backlogs] AS Expr1
FROM Q_Manager_CHS_Total
INNER JOIN
(
select Q_Manager_Backlog_Total.Backlogs, tbl_CEAR_Name.CEAR_Team
FROM Q_Manager_Backlog_Total
INNER JOIN tbl_CEAR_Name
ON Q_Manager_Backlog_Total.CEAR_Team = tbl_CEAR_Name.CEAR_Team
) T1
ON Q_Manager_CHS_Total.CEAR_Team = T1.CEAR_Team
ORDER BY Q_Manager_Backlog_Total.Backlogs DESC;
I suspect the count field [backlogs] in query [q_managers_backlog_total] has 0 as a result somewhere. If you then try to divide by 0 you will evidently get an error. Catch a 0 value in the underlying query and you're good.

aggregate functions are not allowed in WHERE

I am using this query to find the unique records by latest date using postgresql. The error I am having is "aggregate functions are not allowed in WHERE". How to fix error “aggregate functions are not allowed in WHERE” Following this link I have tried to use inner select function. But this did not work. Please help me to edit the query. I am using PgAdmin III as client.
SELECT Distinct t1.pa_serial_
,t1.homeownerm_name
,t1.districtvdc
,t1.date as firstrancheinspection_date
,t1.status
,t1.name_of_data_collector
,t1.fulcrum_id
,first_tranche_inspection_v2_reporting_questionnaire.date_reporting
From first_tranche_inspection_v2 t1
LEFT JOIN first_tranche_inspection_v2_reporting_questionnaire ON (t1.fulcrum_id = first_tranche_inspection_v2_reporting_questionnaire.fulcrum_parent_id)
where first_tranche_inspection_v2_reporting_questionnaire.date_reporting = (
select Max(first_tranche_inspection_v2_reporting_questionnaire.date_reporting)
from first_tranche_inspection_v2
where first_tranche_inspection_v2.pa_serial_ = t1.pa_serial_
);
You want to join the latest reporting questionaire per inspection. In PostgreSQL you can use DISTINCT ON for this:
select fti.*, rq.*
from first_tranche_inspection_v2 fti
left join
(
select distinct on (fulcrum_parent_id) *
from first_tranche_inspection_v2_reporting_questionnaire
order by fulcrum_parent_id, date_reporting desc
) rq on rq.fulcrum_parent_id = fti.fulcrum_id;
Or use standard SQL's ROW_NUMBER:
select fti.*, rq.*
from first_tranche_inspection_v2 fti
left join
(
select
ftirq.*,
row_number() over (partition by fulcrum_parent_id order by date_reporting desc) as rn
from first_tranche_inspection_v2_reporting_questionnaire ftirq
) rq on rq.fulcrum_parent_id = fti.fulcrum_id and rq.rn = 1;
What you were trying to do should look like this:
select fti.*, rq.*
from first_tranche_inspection_v2 fti
left join first_tranche_inspection_v2_reporting_questionnaire rq
on rq.fulcrum_parent_id = fti.fulcrum_id
and (rq.fulcrum_parent_id, rq.date_reporting) in
(
select fulcrum_parent_id, max(date_reporting)
from first_tranche_inspection_v2_reporting_questionnaire
group by fulcrum_parent_id
);
This works, too, and only has the disadvantage that you read the table first_tranche_inspection_v2_reporting_questionnaire twice.
DISTINCT often ends up being implemented with a GROUP BY query in many RDBMS. What I think is happening in your current query is that there is already an implicit aggregation involving the columns in your SELECT. Hence, the correlated subquery involving MAX() actually is an aggregation because of the DISTINCT.
One quick workaround might be to perform the original query without DISTINCT, then subquery the result set to retain only distinct records:
WITH cte AS (
SELECT t1.pa_serial_,
t1.homeownerm_name,
t1.districtvdc,
t1.date as firstrancheinspection_date,
t1.status,
t1.name_of_data_collector,
t1.fulcrum_id,
t2.date_reporting
FROM first_tranche_inspection_v2 t1
LEFT JOIN first_tranche_inspection_v2_reporting_questionnaire t2
ON t1.fulcrum_id = t2.fulcrum_parent_id
WHERE t2.date_reporting = (SELECT MAX(t.date_reporting)
FROM first_tranche_inspection_v2 t
WHERE t.pa_serial_ = t1.pa_serial_)
);
SELECT DISTINCT t.pa_serial_,
t.homeownerm_name,
t.districtvdc,
t.firstrancheinspection_date,
t.status,
t.name_of_data_collector,
t.fulcrum_id,
t.date_reporting
FROM cte t
Note that I went ahead and added an alias to the second table in your join, which leaves the query much easier to read.

Group by query error in multiple joins

I need to fetch each select item and its count in single query.Here is my query and expecting the output as single array.
select ordetable.order_id, count(ordetable.order_id), order_table.name,
count(order_table.na me), orderitem_table.itemname,
count(orderitem_table.itemname)
from order_table
left join orderitem_table
on order_table.order_id = orderitem_table.order_id
group by ordetable.order_id
Am getting this error:
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Column
'orderitem_table.itemname' is invalid in the select list because it is
not contained in either an aggregate function or the GROUP BY clause.
The issue is evident from the error message, isn't it?
Modify your query like below.
select ordetable.order_id, count(ordetable.order_id), order_table.name,
count(order_table.name), orderitem_table.itemname,
count(orderitem_table.itemname)
from order_table
left join orderitem_table
on order_table.order_id = orderitem_table.order_id
group by ordetable.order_id, order_table.name, orderitem_table.itemname
If you not like to group order_table.name and orderitem_table.itemname, then you can use 'min' condition.
select ordetable.order_id, count(ordetable.order_id), min(order_table.name),
count(order_table.name), min(orderitem_table.itemname),
count(orderitem_table.itemname)
from order_table
left join orderitem_table
on order_table.order_id = orderitem_table.order_id
group by ordetable.order_id
Your wording and your query are not in sync. Each item and its count (over all the orders) will be
select orderitem_table.itemname, orderitem_table.itemnumber, count(*)
from order_table
join orderitem_table
on order_table.order_id = orderitem_table.order_id
group by orderitem_table.itemname, orderitem_table.itemnumber